1
0
mirror of https://github.com/zeldaret/oot.git synced 2024-09-22 21:35:27 +00:00
oot/src/code/code_800EC960.c
engineer124 95b4317931
Audio Ocarina Documentation (#1026)
* Begin ocarina documentation

* Many ocarina-related docs

* More ocarina docs

* Introduce Ocarina Fonts Enum

* Fix ocarina font enum

* Fix incorrect documentation, more documentation

* Ocarina recording documentation

* cleanup

* Small touch-ups

* Fix font -> instrument

* format

* Better docs on playback, memory game

* more cleanup

* Add z64ocarina.h

* Clean up names

* final cleanup

* typo

* Fix description

* better docs

* Fix channel -> channelIdx

* Fix old "font" name to correct "instrument" name, add io port docs

* Add comments to clarify certain lines/functions

* format

* Rename noteIdx to pitch

* Missed a name

* Add comment on pitch

* `reset` -> `SetInstrument` and `displayed` -> `playback`

* Clarify audio_update and windmill comment

* Minor PR fixes

* Revert Audio_Update because there are 2 different Audio_Update functions

* PR Feedback

* Ocarina Idx -> Index

* Introduce OCARINA_BTN_C_RIGHT_OR_C_LEFT

* PR Suggestions

* Next PR Suggestions

* Next PR Feedback

* consistency

* Better docs (PR)

* Better comment
2022-05-09 18:59:23 +02:00

5292 lines
177 KiB
C

#include "ultra64.h"
#include "global.h"
// TODO: can these macros be shared between files? code_800F9280 seems to use
// versions without any casts...
#define Audio_DisableSeq(playerIdx, fadeOut) Audio_QueueCmdS32(0x83000000 | ((u8)playerIdx << 16), fadeOut)
#define Audio_StartSeq(playerIdx, fadeTimer, seqId) \
Audio_QueueSeqCmd(0x00000000 | ((u8)playerIdx << 24) | ((u8)(fadeTimer) << 0x10) | (u16)seqId)
#define Audio_SeqCmd7(playerIdx, a, b) \
Audio_QueueSeqCmd(0x70000000 | ((u8)playerIdx << 0x18) | ((u8)a << 0x10) | (u8)(b))
#define Audio_SeqCmdC(playerIdx, a, b, c) \
Audio_QueueSeqCmd(0xC0000000 | ((u8)playerIdx << 24) | ((u8)a << 16) | ((u8)b << 8) | ((u8)(c)))
#define Audio_SeqCmdA(playerIdx, a) Audio_QueueSeqCmd(0xA0000000 | ((u8)playerIdx << 24) | ((u16)(a)))
#define Audio_SeqCmd1(playerIdx, a) Audio_QueueSeqCmd(0x100000FF | ((u8)playerIdx << 24) | ((u8)(a) << 16))
#define Audio_SeqCmdB(playerIdx, a, b, c) \
Audio_QueueSeqCmd(0xB0000000 | ((u8)playerIdx << 24) | ((u8)a << 16) | ((u8)b << 8) | ((u8)c))
#define Audio_SeqCmdB40(playerIdx, a, b) Audio_QueueSeqCmd(0xB0004000 | ((u8)playerIdx << 24) | ((u8)a << 16) | ((u8)b))
#define Audio_SeqCmd6(playerIdx, a, b, c) \
Audio_QueueSeqCmd(0x60000000 | ((u8)playerIdx << 24) | ((u8)(a) << 16) | ((u8)b << 8) | ((u8)c))
#define Audio_SeqCmdE0(playerIdx, a) Audio_QueueSeqCmd(0xE0000000 | ((u8)playerIdx << 24) | ((u8)a))
#define Audio_SeqCmdE01(playerIdx, a) Audio_QueueSeqCmd(0xE0000100 | ((u8)playerIdx << 24) | ((u16)a))
#define Audio_SeqCmd8(playerIdx, a, b, c) \
Audio_QueueSeqCmd(0x80000000 | ((u8)playerIdx << 24) | ((u8)a << 16) | ((u8)b << 8) | ((u8)c))
#define Audio_SeqCmdF(playerIdx, a) Audio_QueueSeqCmd(0xF0000000 | ((u8)playerIdx << 24) | ((u8)a))
#define ABS_ALT(x) ((x) < 0 ? -(x) : (x))
typedef struct {
/* 0x0 */ f32 vol;
/* 0x4 */ f32 freqScale;
/* 0x8 */ s8 reverb;
/* 0x9 */ s8 panSigned;
/* 0xA */ s8 stereoBits;
/* 0xB */ u8 filter;
/* 0xC */ u8 unk_0C;
} SfxPlayerState;
typedef enum {
/* 0x0 */ SFX_CHANNEL_PLAYER0, // SfxPlayerBank
/* 0x1 */ SFX_CHANNEL_PLAYER1,
/* 0x2 */ SFX_CHANNEL_PLAYER2,
/* 0x3 */ SFX_CHANNEL_ITEM0, // SfxItemBank
/* 0x4 */ SFX_CHANNEL_ITEM1,
/* 0x5 */ SFX_CHANNEL_ENV0, // SfxEnvironmentBank
/* 0x6 */ SFX_CHANNEL_ENV1,
/* 0x7 */ SFX_CHANNEL_ENV2,
/* 0x8 */ SFX_CHANNEL_ENEMY0, // SfxEnemyBank
/* 0x9 */ SFX_CHANNEL_ENEMY1,
/* 0xA */ SFX_CHANNEL_ENEMY2,
/* 0xB */ SFX_CHANNEL_SYSTEM0, // SfxSystemBank
/* 0xC */ SFX_CHANNEL_SYSTEM1,
/* 0xD */ SFX_CHANNEL_OCARINA, // SfxOcarinaBank
/* 0xE */ SFX_CHANNEL_VOICE0, // SfxVoiceBank
/* 0xF */ SFX_CHANNEL_VOICE1
} SfxChannelIndex; // playerIdx = 2
typedef struct {
/* 0x0 */ f32 value;
/* 0x4 */ f32 target;
/* 0x8 */ f32 step;
/* 0xC */ s32 remainingFrames;
} FreqLerp;
typedef struct {
/* 0x0 */ u16 playerIO;
/* 0x2 */ u16 channelMask;
/* 0x4 */ u8 channelIO[3 * 33 + 1];
} NatureAmbienceDataIO; // size = 0x68
typedef enum {
/* 0x0 */ PAGE_NON,
/* 0x1 */ PAGE_SOUND_CONTROL,
/* 0x2 */ PAGE_SPEC_INFO, // unused
/* 0x3 */ PAGE_HEAP_INFO,
/* 0x4 */ PAGE_GROUP_TRACK_INFO, // unused
/* 0x5 */ PAGE_SUB_TRACK_INFO,
/* 0x6 */ PAGE_CHANNEL_INFO, // unused
/* 0x7 */ PAGE_INTERFACE_INFO,
/* 0x8 */ PAGE_SFX_SWAP,
/* 0x9 */ PAGE_BLOCK_CHANGE_BGM,
/* 0xA */ PAGE_NATURAL_SOUND_CONTROL, // unused
/* 0xB */ PAGE_OCARINA_TEST,
/* 0xC */ PAGE_SFX_PARAMETER_CHANGE,
/* 0xD */ PAGE_SCROLL_PRINT,
/* 0xE */ PAGE_FREE_AREA,
/* 0xF */ PAGE_MAX
} AudioDebugPage;
#define SCROLL_PRINT_BUF_SIZE 25
typedef struct {
s8 x;
s8 y;
} OcarinaStick;
u8 gIsLargeSoundBank[7] = { 0, 0, 0, 1, 0, 0, 0 };
// Only the first row of these is supported by sequence 0. (gSfxChannelLayout is always 0.)
u8 gChannelsPerBank[4][7] = {
{ 3, 2, 3, 3, 2, 1, 2 },
{ 3, 2, 2, 2, 2, 2, 2 },
{ 3, 2, 2, 2, 2, 2, 2 },
{ 4, 1, 0, 0, 2, 2, 2 },
};
u8 gUsedChannelsPerBank[4][7] = {
{ 3, 2, 3, 2, 2, 1, 1 },
{ 3, 1, 1, 1, 2, 1, 1 },
{ 3, 1, 1, 1, 2, 1, 1 },
{ 2, 1, 0, 0, 1, 1, 1 },
};
f32 D_801305B0 = 0.7950898f;
s8 D_801305B4 = 35;
s8 D_801305B8 = 20;
s8 D_801305BC = 30;
s8 D_801305C0 = 20;
f32 sBehindScreenZ[2] = { -15.0f, -65.0f };
u8 sAudioIncreasingTranspose = 0;
u8 gMorphaTransposeTable[16] = { 0, 0, 0, 1, 1, 2, 4, 6, 8, 8, 8, 8, 8, 8, 8, 8 };
u8 sPrevChargeLevel = 0;
f32 D_801305E4[4] = { 1.0f, 1.12246f, 1.33484f, 1.33484f }; // 2**({0, 2, 5, 5}/12)
f32 D_801305F4 = 1.0f;
u8 sGanonsTowerLevelsVol[8] = { 127, 80, 75, 73, 70, 68, 65, 60 };
u8 sEnterGanonsTowerTimer = 0;
s8 D_80130604 = 2;
s8 D_80130608 = 0;
s8 sAudioCutsceneFlag = 0;
s8 sSpecReverb = 0;
s8 sAudioEnvReverb = 0;
s8 sAudioCodeReverb = 0;
u8 sPrevSeqMode = 0;
f32 sAudioEnemyDist = 0.0f;
s8 sAudioEnemyVol = 127;
u16 sPrevMainBgmSeqId = NA_BGM_DISABLED;
u8 D_8013062C = 0;
u8 D_80130630 = NA_BGM_GENERAL_SFX;
u32 sNumFramesStill = 0;
u32 sNumFramesMoving = 0;
u8 sAudioBaseFilter = 0;
u8 sAudioExtraFilter = 0;
u8 sAudioBaseFilter2 = 0;
u8 sAudioExtraFilter2 = 0;
Vec3f* sSariaBgmPtr = NULL;
f32 D_80130650 = 2000.0f;
u8 sSeqModeInput = 0;
u8 sSeqFlags[0x6E] = {
0x2, // NA_BGM_GENERAL_SFX
0x1, // NA_BGM_NATURE_BACKGROUND
0, // NA_BGM_FIELD_LOGIC
0, // NA_BGM_FIELD_INIT
0, // NA_BGM_FIELD_DEFAULT_1
0, // NA_BGM_FIELD_DEFAULT_2
0, // NA_BGM_FIELD_DEFAULT_3
0, // NA_BGM_FIELD_DEFAULT_4
0, // NA_BGM_FIELD_DEFAULT_5
0, // NA_BGM_FIELD_DEFAULT_6
0, // NA_BGM_FIELD_DEFAULT_7
0, // NA_BGM_FIELD_DEFAULT_8
0, // NA_BGM_FIELD_DEFAULT_9
0, // NA_BGM_FIELD_DEFAULT_A
0, // NA_BGM_FIELD_DEFAULT_B
0, // NA_BGM_FIELD_ENEMY_INIT
0, // NA_BGM_FIELD_ENEMY_1
0, // NA_BGM_FIELD_ENEMY_2
0, // NA_BGM_FIELD_ENEMY_3
0, // NA_BGM_FIELD_ENEMY_4
0, // NA_BGM_FIELD_STILL_1
0, // NA_BGM_FIELD_STILL_2
0, // NA_BGM_FIELD_STILL_3
0, // NA_BGM_FIELD_STILL_4
0x21, // NA_BGM_DUNGEON
0x10, // NA_BGM_KAKARIKO_ADULT
0, // NA_BGM_ENEMY
0x88, // NA_BGM_BOSS
0x1, // NA_BGM_INSIDE_DEKU_TREE
0, // NA_BGM_MARKET
0, // NA_BGM_TITLE
0x20, // NA_BGM_LINK_HOUSE
0, // NA_BGM_GAME_OVER
0, // NA_BGM_BOSS_CLEAR
0x2, // NA_BGM_ITEM_GET
0x4, // NA_BGM_OPENING_GANON
0x2, // NA_BGM_HEART_GET
0x2, // NA_BGM_OCA_LIGHT
0x1, // NA_BGM_JABU_JABU
0x10, // NA_BGM_KAKARIKO_KID
0, // NA_BGM_GREAT_FAIRY
0, // NA_BGM_ZELDA_THEME
0x1, // NA_BGM_FIRE_TEMPLE
0x2, // NA_BGM_OPEN_TRE_BOX
0x1, // NA_BGM_FOREST_TEMPLE
0, // NA_BGM_COURTYARD
0x80, // NA_BGM_GANON_TOWER
0, // NA_BGM_LONLON
0x80, // NA_BGM_GORON_CITY
0, // NA_BGM_FIELD_MORNING
0x2, // NA_BGM_SPIRITUAL_STONE
0x2, // NA_BGM_OCA_BOLERO
0x2, // NA_BGM_OCA_MINUET
0x2, // NA_BGM_OCA_SERENADE
0x2, // NA_BGM_OCA_REQUIEM
0x2, // NA_BGM_OCA_NOCTURNE
0x88, // NA_BGM_MINI_BOSS
0x2, // NA_BGM_SMALL_ITEM_GET
0, // NA_BGM_TEMPLE_OF_TIME
0x2, // NA_BGM_EVENT_CLEAR
0x11, // NA_BGM_KOKIRI
0x2, // NA_BGM_OCA_FAIRY_GET
0x1, // NA_BGM_SARIA_THEME
0x1, // NA_BGM_SPIRIT_TEMPLE
0, // NA_BGM_HORSE
0, // NA_BGM_HORSE_GOAL
0, // NA_BGM_INGO
0x2, // NA_BGM_MEDALLION_GET
0x2, // NA_BGM_OCA_SARIA
0x2, // NA_BGM_OCA_EPONA
0x2, // NA_BGM_OCA_ZELDA
0x2, // NA_BGM_OCA_SUNS
0x2, // NA_BGM_OCA_TIME
0x2, // NA_BGM_OCA_STORM
0, // NA_BGM_NAVI_OPENING
0, // NA_BGM_DEKU_TREE_CS
0, // NA_BGM_WINDMILL
0, // NA_BGM_HYRULE_CS
0x20, // NA_BGM_MINI_GAME
0, // NA_BGM_SHEIK
0x10, // NA_BGM_ZORA_DOMAIN
0x2, // NA_BGM_APPEAR
0, // NA_BGM_ADULT_LINK
0, // NA_BGM_MASTER_SWORD
0x4, // NA_BGM_INTRO_GANON
0x20, // NA_BGM_SHOP
0x40, // NA_BGM_CHAMBER_OF_SAGES
0x40, // NA_BGM_FILE_SELECT
0x1, // NA_BGM_ICE_CAVERN
0x2, // NA_BGM_DOOR_OF_TIME
0x2, // NA_BGM_OWL
0x1, // NA_BGM_SHADOW_TEMPLE
0x1, // NA_BGM_WATER_TEMPLE
0x2, // NA_BGM_BRIDGE_TO_GANONS
0, // NA_BGM_OCARINA_OF_TIME
0x11, // NA_BGM_GERUDO_VALLEY
0, // NA_BGM_POTION_SHOP
0, // NA_BGM_KOTAKE_KOUME
0x80, // NA_BGM_ESCAPE
0, // NA_BGM_UNDERGROUND
0x80, // NA_BGM_GANON_BATTLE_1
0x80, // NA_BGM_GANON_BATTLE_2
0, // NA_BGM_END_DEMO
0, // NA_BGM_STAFF_1
0, // NA_BGM_STAFF_2
0, // NA_BGM_STAFF_3
0, // NA_BGM_STAFF_4
0, // NA_BGM_FIRE_BOSS
0x8, // NA_BGM_TIMED_MINI_GAME
0, // NA_BGM_VARIOUS_SFX
};
s8 sSpecReverbs[20] = { 0, 0, 0, 0, 0, 0, 0, 40, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
NatureAmbienceDataIO sNatureAmbienceDataIO[20] = {
// NATURE_ID_GENERAL_NIGHT
{
0xC0FF, // PlayerIO Data
0xC0FE, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CROWS_CAWS),
NATURE_IO_CRITTER_0_BEND_PITCH(64),
NATURE_IO_CRITTER_0_NUM_LAYERS(0),
NATURE_IO_CRITTER_0_PORT5(32),
// Channel 2
NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_1_BEND_PITCH(0),
NATURE_IO_CRITTER_1_NUM_LAYERS(1),
NATURE_IO_CRITTER_1_PORT5(16),
// Channel 3
NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_SMALL_BIRD_CHIRPS),
NATURE_IO_CRITTER_2_BEND_PITCH(112),
NATURE_IO_CRITTER_2_NUM_LAYERS(1),
NATURE_IO_CRITTER_2_PORT5(48),
// Channel 4
NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_HAWK_SCREECH),
NATURE_IO_CRITTER_3_BEND_PITCH(127),
NATURE_IO_CRITTER_3_NUM_LAYERS(0),
NATURE_IO_CRITTER_3_PORT5(16),
// Channel 5
NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_BIRD_CHIRP_1),
NATURE_IO_CRITTER_4_BEND_PITCH(127),
NATURE_IO_CRITTER_4_NUM_LAYERS(1),
NATURE_IO_CRITTER_4_PORT5(16),
// Channel 6
NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_TAP),
NATURE_IO_CRITTER_5_BEND_PITCH(127),
NATURE_IO_CRITTER_5_NUM_LAYERS(3),
NATURE_IO_CRITTER_5_PORT5(16),
// Channel 7
NATURE_IO_CRITTER_6_TYPE(NATURE_CRITTER_CUCCO_CROWS),
NATURE_IO_CRITTER_6_BEND_PITCH(127),
NATURE_IO_CRITTER_6_NUM_LAYERS(1),
NATURE_IO_CRITTER_6_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_MARKET_ENTRANCE
{
0xC0FB, // PlayerIO Data
0xC0FA, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// Channel 3
NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_BIRD_SCREECH),
NATURE_IO_CRITTER_2_BEND_PITCH(112),
NATURE_IO_CRITTER_2_NUM_LAYERS(1),
NATURE_IO_CRITTER_2_PORT5(48),
// Channel 4
NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_HAWK_SCREECH),
NATURE_IO_CRITTER_3_BEND_PITCH(127),
NATURE_IO_CRITTER_3_NUM_LAYERS(0),
NATURE_IO_CRITTER_3_PORT5(16),
// Channel 5
NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_BIRD_CHIRP_1),
NATURE_IO_CRITTER_4_BEND_PITCH(127),
NATURE_IO_CRITTER_4_NUM_LAYERS(1),
NATURE_IO_CRITTER_4_PORT5(16),
// Channel 6
NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_TAP),
NATURE_IO_CRITTER_5_BEND_PITCH(127),
NATURE_IO_CRITTER_5_NUM_LAYERS(3),
NATURE_IO_CRITTER_5_PORT5(16),
// Channel 7
NATURE_IO_CRITTER_6_TYPE(NATURE_CRITTER_CUCCO_CROWS),
NATURE_IO_CRITTER_6_BEND_PITCH(127),
NATURE_IO_CRITTER_6_NUM_LAYERS(1),
NATURE_IO_CRITTER_6_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_KAKARIKO_REGION
{
0xC001, // PlayerIO Data
0x4000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 2
NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_BIRD_SCREECH),
NATURE_IO_CRITTER_1_BEND_PITCH(48),
NATURE_IO_CRITTER_1_NUM_LAYERS(1),
NATURE_IO_CRITTER_1_PORT5(32),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_MARKET_RUINS
{
0xC005, // PlayerIO Data
0x4000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_HOWLING_WIND),
NATURE_IO_STREAM_0_PORT3(32),
// Channel 2
NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_BIRD_SCREECH),
NATURE_IO_CRITTER_1_BEND_PITCH(48),
NATURE_IO_CRITTER_1_NUM_LAYERS(1),
NATURE_IO_CRITTER_1_PORT5(32),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_KOKIRI_REGION
{
0xC01F, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(47),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_OWL_HOOT),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// Channel 2
NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_CAWING_BIRD),
NATURE_IO_CRITTER_1_BEND_PITCH(0),
NATURE_IO_CRITTER_1_NUM_LAYERS(1),
NATURE_IO_CRITTER_1_PORT5(32),
// Channel 3
NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_HAWK_SCREECH),
NATURE_IO_CRITTER_2_BEND_PITCH(0),
NATURE_IO_CRITTER_2_NUM_LAYERS(0),
NATURE_IO_CRITTER_2_PORT5(44),
// Channel 4
NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_BIRD_SCREECH),
NATURE_IO_CRITTER_3_BEND_PITCH(63),
NATURE_IO_CRITTER_3_NUM_LAYERS(1),
NATURE_IO_CRITTER_3_PORT5(44),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_MARKET_NIGHT
{
0xC003, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_06
{
0xC0FB, // PlayerIO Data
0xC0FA, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// Channel 3
NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_BIRD_SCREECH),
NATURE_IO_CRITTER_2_BEND_PITCH(112),
NATURE_IO_CRITTER_2_NUM_LAYERS(1),
NATURE_IO_CRITTER_2_PORT5(48),
// Channel 4
NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_HAWK_SCREECH),
NATURE_IO_CRITTER_3_BEND_PITCH(127),
NATURE_IO_CRITTER_3_NUM_LAYERS(0),
NATURE_IO_CRITTER_3_PORT5(16),
// Channel 5
NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_BIRD_CHIRP_1),
NATURE_IO_CRITTER_4_BEND_PITCH(127),
NATURE_IO_CRITTER_4_NUM_LAYERS(1),
NATURE_IO_CRITTER_4_PORT5(16),
// Channel 6
NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_TAP),
NATURE_IO_CRITTER_5_BEND_PITCH(127),
NATURE_IO_CRITTER_5_NUM_LAYERS(3),
NATURE_IO_CRITTER_5_PORT5(16),
// Channel 7
NATURE_IO_CRITTER_6_TYPE(NATURE_CRITTER_CUCCO_CROWS),
NATURE_IO_CRITTER_6_BEND_PITCH(127),
NATURE_IO_CRITTER_6_NUM_LAYERS(1),
NATURE_IO_CRITTER_6_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_GANONS_LAIR
{
0x8001, // PlayerIO Data
0x0, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_HOWLING_WIND),
NATURE_IO_STREAM_0_PORT3(32),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_08
{
0xC003, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_09
{
0xC003, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_WASTELAND
{
0xC001, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_SCREECHING_WIND),
NATURE_IO_STREAM_0_PORT3(0),
NATURE_IO_STREAM_0_PORT4(0),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_COLOSSUS
{
0xC02F, // PlayerIO Data
0xC02E, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_SCREECHING_WIND),
NATURE_IO_STREAM_0_PORT3(0),
NATURE_IO_STREAM_0_PORT4(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_SMALL_BIRD_CHIRPS),
NATURE_IO_CRITTER_0_BEND_PITCH(64),
NATURE_IO_CRITTER_0_NUM_LAYERS(0),
NATURE_IO_CRITTER_0_PORT5(32),
// Channel 2
NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_BIRD_CALL),
NATURE_IO_CRITTER_1_BEND_PITCH(112),
NATURE_IO_CRITTER_1_NUM_LAYERS(1),
NATURE_IO_CRITTER_1_PORT5(48),
// Channel 3
NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_HAWK_SCREECH),
NATURE_IO_CRITTER_2_BEND_PITCH(127),
NATURE_IO_CRITTER_2_NUM_LAYERS(0),
NATURE_IO_CRITTER_2_PORT5(16),
// Channel 5
NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_4_BEND_PITCH(127),
NATURE_IO_CRITTER_4_NUM_LAYERS(0),
NATURE_IO_CRITTER_4_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_DEATH_MOUNTAIN_TRAIL
{
0xC07F, // PlayerIO Data
0xC07E, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
NATURE_IO_STREAM_0_PORT4(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_SMALL_BIRD_CHIRPS),
NATURE_IO_CRITTER_0_BEND_PITCH(64),
NATURE_IO_CRITTER_0_NUM_LAYERS(0),
NATURE_IO_CRITTER_0_PORT5(32),
// Channel 2
NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_BIRD_SCREECH),
NATURE_IO_CRITTER_1_BEND_PITCH(112),
NATURE_IO_CRITTER_1_NUM_LAYERS(1),
NATURE_IO_CRITTER_1_PORT5(48),
// Channel 3
NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_BIRD_SONG),
NATURE_IO_CRITTER_2_BEND_PITCH(127),
NATURE_IO_CRITTER_2_NUM_LAYERS(0),
NATURE_IO_CRITTER_2_PORT5(16),
// Channel 4
NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_LOUD_CHIRPING),
NATURE_IO_CRITTER_3_BEND_PITCH(0),
NATURE_IO_CRITTER_3_NUM_LAYERS(0),
NATURE_IO_CRITTER_3_PORT5(16),
// Channel 5
NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_BIRD_CHIRP_1),
NATURE_IO_CRITTER_4_BEND_PITCH(0),
NATURE_IO_CRITTER_4_NUM_LAYERS(0),
NATURE_IO_CRITTER_4_PORT5(16),
// Channel 6
NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_TAP),
NATURE_IO_CRITTER_5_BEND_PITCH(0),
NATURE_IO_CRITTER_5_NUM_LAYERS(0),
NATURE_IO_CRITTER_5_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_0D
{
0xC003, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_0E
{
0xC003, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_0F
{
0xC01F, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_BIRD_CHIRP_1),
NATURE_IO_CRITTER_0_BEND_PITCH(80),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(8),
// Channel 2
NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_SMALL_BIRD_CHIRPS),
NATURE_IO_CRITTER_1_BEND_PITCH(80),
NATURE_IO_CRITTER_1_NUM_LAYERS(1),
NATURE_IO_CRITTER_1_PORT5(48),
// Channel 3
NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_LOUD_CHIRPING),
NATURE_IO_CRITTER_2_BEND_PITCH(0),
NATURE_IO_CRITTER_2_NUM_LAYERS(0),
NATURE_IO_CRITTER_2_PORT5(0),
// Channel 4
NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_BIRD_SCREECH),
NATURE_IO_CRITTER_3_BEND_PITCH(96),
NATURE_IO_CRITTER_3_NUM_LAYERS(0),
NATURE_IO_CRITTER_3_PORT5(32),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_10
{
0xC003, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_11
{
0xC003, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_12
{
0xC003, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
// NATURE_ID_NONE
// While there is data for this natureAmbienceId, it is identical to previous entries
// and the game treats it as no nature ambience
{
0xC003, // PlayerIO Data
0xC000, // Channel Mask
{
// Channel 0
NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER),
NATURE_IO_STREAM_0_PORT3(0),
// Channel 1
NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS),
NATURE_IO_CRITTER_0_BEND_PITCH(0),
NATURE_IO_CRITTER_0_NUM_LAYERS(1),
NATURE_IO_CRITTER_0_PORT5(16),
// End
NATURE_IO_ENTRIES_END,
},
},
};
u32 sOcarinaAllowedButtonMask = (BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP);
s32 sOcarinaAButtonMap = BTN_A;
s32 sOcarinaCUpButtonMap = BTN_CUP;
s32 sOcarinaCDownButtonMap = BTN_CDOWN;
u8 sIsOcarinaInputEnabled = false;
s8 sOcarinaInstrumentId = OCARINA_INSTRUMENT_OFF;
u8 sCurOcarinaPitch = OCARINA_PITCH_NONE;
u8 sPrevOcarinaPitch = OCARINA_PITCH_C4;
u8 sCurOcarinaButtonIndex = OCARINA_BTN_A;
u8 sMusicStaffPrevPitch = OCARINA_PITCH_C4;
f32 sCurOcarinaBendFreq = 1.0f;
f32 sRelativeOcarinaVolume = 87.0f / 127.0f;
s8 sCurOcarinaBendIndex = 0;
s8 sCurOcarinaVolume = 87;
s8 sCurOcarinaVibrato = 0;
u8 sPlaybackState = 0;
u32 sOcarinaFlags = 0;
u32 sPlaybackNoteTimer = 0;
u16 sPlaybackNotePos = 0;
u16 sPlaybackStaffPos = 0;
u16 sPrevOcarinaWithMusicStaffFlags = 0;
u8 sPlaybackPitch = OCARINA_PITCH_NONE; // Pitch + PitchFlags
u8 sNotePlaybackVolume = 0;
u8 sNotePlaybackVibrato = 0;
s8 sNotePlaybackBend = 0;
f32 sRelativeNotePlaybackBend = 1.0f;
f32 sRelativeNotePlaybackVolume = 1.0f;
s32 sOcarinaPlaybackTaskStart = 0;
u8 sButtonToPitchMap[5] = {
OCARINA_PITCH_D4, // OCARINA_BTN_A
OCARINA_PITCH_F4, // OCARINA_BTN_C_DOWN
OCARINA_PITCH_A4, // OCARINA_BTN_C_RIGHT
OCARINA_PITCH_B4, // OCARINA_BTN_C_LEFT
OCARINA_PITCH_D5, // OCARINA_BTN_C_UP
};
u8 sOcaMemoryGameAppendPos = 0;
u8 sOcaMemoryGameEndPos = 0;
u8 sOcaMemoryGameNumNotes[] = { 5, 6, 8 };
OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = {
// OCARINA_SONG_MINUET
{
{ OCARINA_PITCH_D4, 18, 86, 0, 0, 0 },
{ OCARINA_PITCH_D5, 18, 92, 0, 0, 0 },
{ OCARINA_PITCH_B4, 72, 86, 0, 0, 0 },
{ OCARINA_PITCH_A4, 18, 80, 0, 0, 0 },
{ OCARINA_PITCH_B4, 18, 88, 0, 0, 0 },
{ OCARINA_PITCH_A4, 144, 86, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 86, 0, 0, 0 },
},
// OCARINA_SONG_BOLERO
{
{ OCARINA_PITCH_F4, 15, 80, 0, 0, 0 },
{ OCARINA_PITCH_D4, 15, 72, 0, 0, 0 },
{ OCARINA_PITCH_F4, 15, 84, 0, 0, 0 },
{ OCARINA_PITCH_D4, 15, 76, 0, 0, 0 },
{ OCARINA_PITCH_A4, 15, 84, 0, 0, 0 },
{ OCARINA_PITCH_F4, 15, 74, 0, 0, 0 },
{ OCARINA_PITCH_A4, 15, 78, 0, 0, 0 },
{ OCARINA_PITCH_F4, 135, 66, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 },
},
// OCARINA_SONG_SERENADE
{
{ OCARINA_PITCH_D4, 36, 60, 0, 0, 0 },
{ OCARINA_PITCH_F4, 36, 78, 0, 0, 0 },
{ OCARINA_PITCH_A4, 33, 82, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 3, 82, 0, 0, 0 },
{ OCARINA_PITCH_A4, 36, 84, 0, 0, 0 },
{ OCARINA_PITCH_B4, 144, 90, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 },
},
// OCARINA_SONG_REQUIEM
{
{ OCARINA_PITCH_D4, 45, 88, 0, 0, 0 },
{ OCARINA_PITCH_F4, 23, 86, 0, 0, 0 },
{ OCARINA_PITCH_D4, 22, 84, 0, 0, 0 },
{ OCARINA_PITCH_A4, 45, 86, 0, 0, 0 },
{ OCARINA_PITCH_F4, 45, 94, 0, 0, 0 },
{ OCARINA_PITCH_D4, 180, 94, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 94, 0, 0, 0 },
},
// OCARINA_SONG_NOCTURNE
{
{ OCARINA_PITCH_B4, 36, 88, 0, 0, 0 },
{ OCARINA_PITCH_A4, 33, 84, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 },
{ OCARINA_PITCH_A4, 18, 82, 0, 0, 0 },
{ OCARINA_PITCH_D4, 18, 60, 0, 0, 0 },
{ OCARINA_PITCH_B4, 18, 90, 0, 0, 0 },
{ OCARINA_PITCH_A4, 18, 88, 0, 0, 0 },
{ OCARINA_PITCH_F4, 144, 96, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 96, 0, 0, 0 },
},
// OCARINA_SONG_PRELUDE
{
{ OCARINA_PITCH_D5, 15, 84, 0, 0, 0 },
{ OCARINA_PITCH_A4, 45, 88, 0, 0, 0 },
{ OCARINA_PITCH_D5, 15, 88, 0, 0, 0 },
{ OCARINA_PITCH_A4, 15, 82, 0, 0, 0 },
{ OCARINA_PITCH_B4, 15, 86, 0, 0, 0 },
{ OCARINA_PITCH_D5, 60, 90, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 75, 90, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 },
},
// OCARINA_SONG_SARIAS
{
{ OCARINA_PITCH_F4, 17, 84, 0, 0, 0 },
{ OCARINA_PITCH_A4, 17, 88, 0, 0, 0 },
{ OCARINA_PITCH_B4, 34, 80, 0, 0, 0 },
{ OCARINA_PITCH_F4, 17, 84, 0, 0, 0 },
{ OCARINA_PITCH_A4, 17, 88, 0, 0, 0 },
{ OCARINA_PITCH_B4, 136, 80, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 },
},
// OCARINA_SONG_EPONAS
{
{ OCARINA_PITCH_D5, 18, 84, 0, 0, 0 },
{ OCARINA_PITCH_B4, 18, 88, 0, 0, 0 },
{ OCARINA_PITCH_A4, 72, 80, 0, 0, 0 },
{ OCARINA_PITCH_D5, 18, 84, 0, 0, 0 },
{ OCARINA_PITCH_B4, 18, 88, 0, 0, 0 },
{ OCARINA_PITCH_A4, 144, 80, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 },
},
// OCARINA_SONG_LULLABY
{
{ OCARINA_PITCH_B4, 51, 84, 0, 0, 0 },
{ OCARINA_PITCH_D5, 25, 88, 0, 0, 0 },
{ OCARINA_PITCH_A4, 78, 80, 0, 0, 0 },
{ OCARINA_PITCH_B4, 51, 84, 0, 0, 0 },
{ OCARINA_PITCH_D5, 25, 88, 0, 0, 0 },
{ OCARINA_PITCH_A4, 100, 80, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 },
},
// OCARINA_SONG_SUNS
{
{ OCARINA_PITCH_A4, 12, 84, 0, 0, 0 },
{ OCARINA_PITCH_F4, 13, 88, 0, 0, 0 },
{ OCARINA_PITCH_D5, 29, 80, 2, 0, 0 },
{ OCARINA_PITCH_NONE, 9, 84, 0, 0, 0 },
{ OCARINA_PITCH_A4, 12, 84, 0, 0, 0 },
{ OCARINA_PITCH_F4, 13, 88, 0, 0, 0 },
{ OCARINA_PITCH_D5, 120, 80, 3, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 },
},
// OCARINA_SONG_TIME
{
{ OCARINA_PITCH_A4, 32, 84, 0, 0, 0 },
{ OCARINA_PITCH_D4, 65, 88, 0, 0, 0 },
{ OCARINA_PITCH_F4, 33, 80, 0, 0, 0 },
{ OCARINA_PITCH_A4, 32, 84, 0, 0, 0 },
{ OCARINA_PITCH_D4, 65, 88, 0, 0, 0 },
{ OCARINA_PITCH_F4, 99, 80, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 },
},
// OCARINA_SONG_STORMS
{
{ OCARINA_PITCH_D4, 11, 84, 0, 0, 0 },
{ OCARINA_PITCH_F4, 11, 88, 0, 0, 0 },
{ OCARINA_PITCH_D5, 45, 80, 0, 0, 0 },
{ OCARINA_PITCH_D4, 11, 84, 0, 0, 0 },
{ OCARINA_PITCH_F4, 11, 88, 0, 0, 0 },
{ OCARINA_PITCH_D5, 90, 80, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 },
},
// OCARINA_SONG_SCARECROW_SPAWN
{
{ OCARINA_PITCH_D4, 3, 0, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 255, 0, 0, 0 },
},
// OCARINA_SONG_MEMORY_GAME
{
{ OCARINA_PITCH_D4, 3, 0, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 },
},
};
OcarinaNote* sPlaybackSong = sOcarinaSongNotes[0];
u8 sFrogsSongNotes[14] = {
OCARINA_BTN_A, OCARINA_BTN_C_LEFT, OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_DOWN, OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_DOWN, OCARINA_BTN_A, OCARINA_BTN_C_DOWN, OCARINA_BTN_A,
OCARINA_BTN_C_DOWN, OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_LEFT, OCARINA_BTN_A,
};
u8* gFrogsSongPtr = sFrogsSongNotes;
u8 sRecordingState = OCARINA_RECORD_OFF;
u8 sRecordSongPos = 0;
u32 sOcarinaRecordTaskStart = 0;
u8 sRecordOcarinaPitch = 0;
u8 sRecordOcarinaVolume = 0;
u8 sRecordOcarinaVibrato = 0;
s8 sRecordOcarinaBendIndex = 0;
u8 sRecordOcarinaButtonIndex = 0;
u8 sPlayedOcarinaSongIndexPlusOne = 0;
u8 sMusicStaffNumNotesPerTest = 0;
u8 sOcarinaDropInputTimer = 0;
OcarinaNote sScarecrowsLongSongNotes[108] = {
{ OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 },
{ OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 },
};
OcarinaNote* gScarecrowLongSongPtr = sScarecrowsLongSongNotes;
u8* gScarecrowSpawnSongPtr = (u8*)&sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN];
OcarinaNote* sMemoryGameSongPtr = sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME];
u8 sPitchToButtonMap[16] = {
OCARINA_BTN_A, // OCARINA_PITCH_C4
OCARINA_BTN_A, // OCARINA_PITCH_DFLAT4
OCARINA_BTN_A, // OCARINA_PITCH_D4
OCARINA_BTN_A, // OCARINA_PITCH_EFLAT4
OCARINA_BTN_C_DOWN, // OCARINA_PITCH_E4
OCARINA_BTN_C_DOWN, // OCARINA_PITCH_F4
OCARINA_BTN_C_DOWN, // OCARINA_PITCH_GFLAT4
OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_G4
OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_AFLAT4
OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_A4
OCARINA_BTN_C_RIGHT_OR_C_LEFT, // OCARINA_PITCH_BFLAT4: Interface/Overlap between C_RIGHT and C_LEFT
OCARINA_BTN_C_LEFT, // OCARINA_PITCH_B4
OCARINA_BTN_C_LEFT, // OCARINA_PITCH_C5
OCARINA_BTN_C_UP, // OCARINA_PITCH_DFLAT5
OCARINA_BTN_C_UP, // OCARINA_PITCH_D5
OCARINA_BTN_C_UP, // OCARINA_PITCH_EFLAT5
};
OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = {
// OCARINA_SONG_MINUET
{ 6,
{
OCARINA_BTN_A,
OCARINA_BTN_C_UP,
OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_RIGHT,
} },
// OCARINA_SONG_BOLERO
{ 8,
{
OCARINA_BTN_C_DOWN,
OCARINA_BTN_A,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_A,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_DOWN,
} },
// OCARINA_SONG_SERENADE
{ 5,
{
OCARINA_BTN_A,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_LEFT,
} },
// OCARINA_SONG_REQUIEM
{ 6,
{
OCARINA_BTN_A,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_A,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_A,
} },
// OCARINA_SONG_NOCTURNE
{ 7,
{
OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_A,
OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_DOWN,
} },
// OCARINA_SONG_PRELUDE
{ 6,
{
OCARINA_BTN_C_UP,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_UP,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_UP,
} },
// OCARINA_SONG_SARIAS
{ 6,
{
OCARINA_BTN_C_DOWN,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_LEFT,
} },
// OCARINA_SONG_EPONAS
{ 6,
{
OCARINA_BTN_C_UP,
OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_UP,
OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_RIGHT,
} },
// OCARINA_SONG_LULLABY
{ 6,
{
OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_UP,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_LEFT,
OCARINA_BTN_C_UP,
OCARINA_BTN_C_RIGHT,
} },
// OCARINA_SONG_SUNS
{ 6,
{
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_C_UP,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_C_UP,
} },
// OCARINA_SONG_TIME
{ 6,
{
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_A,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_C_RIGHT,
OCARINA_BTN_A,
OCARINA_BTN_C_DOWN,
} },
// OCARINA_SONG_STORMS
{ 6,
{
OCARINA_BTN_A,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_C_UP,
OCARINA_BTN_A,
OCARINA_BTN_C_DOWN,
OCARINA_BTN_C_UP,
} },
// OCARINA_SONG_SCARECROW_SPAWN
{ 8, { 0 } },
// OCARINA_SONG_MEMORY_GAME
{ 0, { 0 } },
};
u32 sAudioUpdateStartTime;
u32 sAudioUpdateEndTime;
f32 D_8016B7A8;
f32 D_8016B7AC;
f32 D_8016B7B0;
f32 D_8016B7B4;
FreqLerp sRiverFreqScaleLerp;
FreqLerp sWaterfallFreqScaleLerp;
f32 D_8016B7D8;
s8 D_8016B7DC;
f32 D_8016B7E0;
u16 D_8016B7E4;
struct {
s8 str[5];
u16 num;
} sAudioScrPrtBuf[SCROLL_PRINT_BUF_SIZE];
u8 sRiverSoundMainBgmVol;
u8 sRiverSoundMainBgmCurrentVol;
u8 sRiverSoundMainBgmLower;
u8 sRiverSoundMainBgmRestore;
u8 sGanonsTowerVol;
SfxPlayerState sSfxChannelState[0x10];
char sBinToStrBuf[0x20];
u8 D_8016B9D8;
u8 sAudioSpecPeakNumNotes[0x12];
u8 D_8016B9F2;
u8 D_8016B9F3;
u8 D_8016B9F4;
u16 D_8016B9F6;
OcarinaStaff sPlayingStaff;
OcarinaStaff sPlaybackStaff;
OcarinaStaff sRecordingStaff;
u32 sOcarinaUpdateTaskStart;
OcarinaStick sOcarinaInputStickRel;
u32 sOcarinaInputButtonCur;
u32 sOcarinaInputButtonStart;
u32 sOcarinaInputButtonPrev;
s32 sOcarinaInputButtonPress;
s32 sOcarinaUnused;
u8 sCurOcarinaSongWithoutMusicStaff[8];
u8 sOcarinaWithoutMusicStaffPos;
u8 sOcarinaHasStartedSong;
u8 sFirstOcarinaSongIndex;
u8 sLastOcarinaSongIndex;
u16 sAvailOcarinaSongFlags;
u8 sStaffOcarinaPlayingPos;
u16 sMusicStaffPos[OCARINA_SONG_MAX];
u16 sMusicStaffCurHeldLength[OCARINA_SONG_MAX];
u16 sMusicStaffExpectedLength[OCARINA_SONG_MAX];
u8 sMusicStaffExpectedPitch[OCARINA_SONG_MAX];
OcarinaNote sScarecrowsLongSongSecondNote;
u8 sAudioHasMalonBgm;
f32 sAudioMalonBgmDist;
void PadMgr_RequestPadData(PadMgr* padmgr, Input* inputs, s32 mode);
void Audio_StepFreqLerp(FreqLerp* lerp);
void func_800F56A8(void);
void Audio_PlayNatureAmbienceSequence(u8 natureAmbienceId);
s32 Audio_SetGanonsTowerBgmVolume(u8 targetVol);
// =========== Audio Ocarina ===========
void AudioOcarina_SetCustomButtonMapping(u8 useCustom) {
if (!useCustom) {
osSyncPrintf("AUDIO : Ocarina Control Assign Normal\n");
sOcarinaAllowedButtonMask = (BTN_A | BTN_CUP | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT);
sOcarinaAButtonMap = BTN_A;
sOcarinaCUpButtonMap = BTN_CUP;
sOcarinaCDownButtonMap = BTN_CDOWN;
} else {
osSyncPrintf("AUDIO : Ocarina Control Assign Custom\n");
sOcarinaAllowedButtonMask = (BTN_A | BTN_B | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT);
sOcarinaAButtonMap = BTN_B;
sOcarinaCUpButtonMap = BTN_CDOWN;
sOcarinaCDownButtonMap = BTN_A;
}
}
void AudioOcarina_ReadControllerInput(void) {
Input inputs[4];
Input* input = &inputs[0];
u32 ocarinaInputButtonPrev = sOcarinaInputButtonCur;
PadMgr_RequestPadData(&gPadMgr, inputs, 0);
sOcarinaInputButtonCur = input->cur.button;
sOcarinaInputButtonPrev = ocarinaInputButtonPrev;
sOcarinaInputStickRel.x = input->rel.stick_x;
sOcarinaInputStickRel.y = input->rel.stick_y;
}
/**
* Looks up the frequency to bend the pitch by.
* The pitch will bend up to a maximum of 2 semitones
* in each direction giving a total range of 4 semitones
*/
f32 AudioOcarina_BendPitchTwoSemitones(s8 bendIndex) {
s8 adjBendIndex;
f32 bendFreq;
if (bendIndex > 64) {
adjBendIndex = 127;
} else if (bendIndex < -64) {
adjBendIndex = -128;
} else if (bendIndex >= 0) {
adjBendIndex = (bendIndex * 127) / 64;
} else {
adjBendIndex = (bendIndex * 128) / 64;
}
/**
* index 128 is in the middle of the table and
* contains the value 1.0f i.e. no bend
* absolute indices above 128 will bend the pitch 2 semitones upwards
* absolute indices below 128 will bend the pitch 2 semitones downwards
*/
bendFreq = gBendPitchTwoSemitonesFrequencies[adjBendIndex + 128];
return bendFreq;
}
/**
* If an available song has been played, then return that song index
* If the ocarina is on, but no song has been played then return 0xFE
* If the ocarina is off, return 0xFF
*/
u8 AudioOcarina_GetPlayingState(void) {
u8 playedOcarinaSongIndex;
if (sPlayedOcarinaSongIndexPlusOne != 0) {
playedOcarinaSongIndex = sPlayedOcarinaSongIndexPlusOne - 1;
sPlayedOcarinaSongIndexPlusOne = 0;
} else if (sOcarinaFlags != 0) {
playedOcarinaSongIndex = 0xFE;
} else {
playedOcarinaSongIndex = 0xFF;
}
return playedOcarinaSongIndex;
}
u8 AudioOcarina_MapNoteToButton(u8 pitchAndBFlatFlag) {
u8 buttonIndex = sPitchToButtonMap[pitchAndBFlatFlag & 0x3F];
/**
* Special case for bFlat4:
* CRIGHT and CLEFT are the only two pitches that are 2 semitones apart
* which are pitches A4 and B4 respectively
* bFlat4 is in the middle of those two and is the only pitches that can not
* be resolved between the two buttons without external information.
* That information is stored as flags in pitch with the mask:
* (pitchAndBFlatFlag & 0xC0)
*/
if (buttonIndex == OCARINA_BTN_C_RIGHT_OR_C_LEFT) {
if (pitchAndBFlatFlag & 0x80) {
return OCARINA_BTN_C_RIGHT;
}
return OCARINA_BTN_C_LEFT;
}
return buttonIndex;
}
void AudioOcarina_MapNotesToScarecrowButtons(u8 noteSongIndex) {
u8 buttonSongPos = 0;
u8 noteSongPos = 0;
u8 pitch;
while (buttonSongPos < 8 && noteSongPos < 16) {
pitch = sOcarinaSongNotes[noteSongIndex][noteSongPos++].pitch;
if (pitch != OCARINA_PITCH_NONE) {
gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonsIndex[buttonSongPos++] = sPitchToButtonMap[pitch];
}
}
}
/**
* Ocarina flags:
* bitmask 0x3FFF:
* - Ocarina song id
* bitmask 0xC000:
* - 0x0000: Limits the notes to 8 notes at a time. Not playing a correct song after 8 notes will cause an ocarina
* error
* - 0x4000: (Identical to 0xC000)
* - 0x8000: Limits the notes to 1 note at a time. A single incorrect note will cause an ocarina error
* - 0xC000: Free-play, no limitations to the number of notes to play
* bitmask 0x7FFF0000:
* - ocarina action (only used to make flags != 0)
* bitmask 0x80000000:
* - unused (only used to make flags != 0)
*/
void AudioOcarina_Start(u16 ocarinaFlags) {
u8 i;
if ((sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF) && ((ocarinaFlags & 0xFFF) == 0xFFF)) {
ocarinaFlags |= 0x1000;
}
if ((ocarinaFlags == 0xCFFF) && (sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF)) {
ocarinaFlags = 0xDFFF;
}
if ((ocarinaFlags == 0xFFF) && (sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF)) {
ocarinaFlags = 0x1FFF;
}
if (ocarinaFlags != 0xFFFF) {
sOcarinaFlags = 0x80000000 + (u32)ocarinaFlags;
sFirstOcarinaSongIndex = 0;
sLastOcarinaSongIndex = OCARINA_SONG_MAX;
if (ocarinaFlags != 0xA000) {
sLastOcarinaSongIndex--;
}
sAvailOcarinaSongFlags = ocarinaFlags & 0x3FFF;
sMusicStaffNumNotesPerTest = 8; // Ocarina Check
sOcarinaHasStartedSong = false;
sPlayedOcarinaSongIndexPlusOne = 0;
sStaffOcarinaPlayingPos = 0;
sPlayingStaff.state = AudioOcarina_GetPlayingState();
sIsOcarinaInputEnabled = true;
sPrevOcarinaWithMusicStaffFlags = 0;
// Reset music staff song check
for (i = 0; i < OCARINA_SONG_MAX; i++) {
sMusicStaffPos[i] = 0;
sMusicStaffCurHeldLength[i] = 0;
sMusicStaffExpectedLength[i] = 0;
sMusicStaffExpectedPitch[i] = 0;
}
if (ocarinaFlags & 0x8000) {
sMusicStaffNumNotesPerTest = 0; // Ocarina Playback
}
if (ocarinaFlags & 0x4000) {
sOcarinaWithoutMusicStaffPos = 0;
}
if (ocarinaFlags & 0xD000) {
AudioOcarina_MapNotesToScarecrowButtons(OCARINA_SONG_SCARECROW_SPAWN);
}
} else {
sOcarinaFlags = 0;
sIsOcarinaInputEnabled = false;
}
}
void AudioOcarina_CheckIfStartedSong(void) {
if (sCurOcarinaPitch != OCARINA_PITCH_NONE && !sOcarinaHasStartedSong) {
sOcarinaHasStartedSong = true;
sMusicStaffPrevPitch = OCARINA_PITCH_NONE;
}
}
/**
* Checks for ocarina songs from user input with a music staff prompt
* Type 1) Playback: tests note-by-note (ocarinaFlag & 0xC000 == 0x8000) eg:
* - learning a new song
* - playing the ocarina memory game
* Type 2) Check: tests in 8-note chunks (ocarinaFlag & 0xC000 == 0x0000) eg:
* - validating scarecrow spawn song as adult
* - ocarina prompt for zelda's lullaby, saria's song, Storms, Song of Time, etc...
*/
void AudioOcarina_CheckSongsWithMusicStaff(void) {
u16 curOcarinaSongFlag;
u16 pad;
u8 noNewValidInput = false;
u16 pad2;
s8 staffOcarinaPlayingPosOffset = 0;
u8 songIndex;
OcarinaNote* curNote;
OcarinaNote* nextNote;
AudioOcarina_CheckIfStartedSong();
if (!sOcarinaHasStartedSong) {
return;
}
if (ABS_ALT(sCurOcarinaBendIndex) > 20) {
sOcarinaFlags = 0;
return;
}
// clang-format off
if (sPrevOcarinaPitch == sCurOcarinaPitch || sCurOcarinaPitch == OCARINA_PITCH_NONE) { noNewValidInput = true; }
// clang-format on
for (songIndex = sFirstOcarinaSongIndex; songIndex < sLastOcarinaSongIndex; songIndex++) {
curOcarinaSongFlag = 1 << songIndex;
if (sAvailOcarinaSongFlags & curOcarinaSongFlag) {
sMusicStaffCurHeldLength[songIndex] = sMusicStaffExpectedLength[songIndex] + 18;
if (noNewValidInput) {
if ((sMusicStaffCurHeldLength[songIndex] >= sMusicStaffExpectedLength[songIndex] - 18) &&
(sMusicStaffCurHeldLength[songIndex] >= sMusicStaffExpectedLength[songIndex] + 18) &&
(sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].length == 0) &&
(sMusicStaffPrevPitch == sMusicStaffExpectedPitch[songIndex])) {
// This case is taken if the song is finished and successfully played
// (i.e. .length == 0 indicates that the song is at the end)
sPlayedOcarinaSongIndexPlusOne = songIndex + 1;
sIsOcarinaInputEnabled = false;
sOcarinaFlags = 0;
}
} else if (sMusicStaffCurHeldLength[songIndex] >= (sMusicStaffExpectedLength[songIndex] - 18)) {
// This else-if statement always holds true, taken if a new note is played
if (sMusicStaffPrevPitch != OCARINA_PITCH_NONE) {
// New note is played
if (sMusicStaffPrevPitch == sMusicStaffExpectedPitch[songIndex]) {
// Note is part of expected song
if (songIndex == OCARINA_SONG_SCARECROW_SPAWN) {
sMusicStaffCurHeldLength[songIndex] = 0;
}
} else {
// Note is not part of expected song, so this song is no longer available as an option in this
// playback
sAvailOcarinaSongFlags ^= curOcarinaSongFlag;
}
}
curNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]];
nextNote = &sOcarinaSongNotes[songIndex][++sMusicStaffPos[songIndex]];
sMusicStaffExpectedLength[songIndex] = curNote->length;
sMusicStaffExpectedPitch[songIndex] = curNote->pitch;
// The current note is not the expected note.
if (sCurOcarinaPitch != sMusicStaffExpectedPitch[songIndex]) {
sAvailOcarinaSongFlags ^= curOcarinaSongFlag;
}
while (curNote->pitch == nextNote->pitch ||
(nextNote->pitch == OCARINA_BTN_INVALID && nextNote->length != 0)) {
sMusicStaffExpectedLength[songIndex] += nextNote->length;
curNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]];
nextNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex] + 1];
sMusicStaffPos[songIndex]++;
}
} else if (sMusicStaffCurHeldLength[songIndex] < 10) {
// case never taken
staffOcarinaPlayingPosOffset = -1;
sMusicStaffCurHeldLength[songIndex] = 0;
sMusicStaffPrevPitch = sCurOcarinaPitch;
} else {
// case never taken
sAvailOcarinaSongFlags ^= curOcarinaSongFlag;
}
}
// if a note is played that doesn't match a song, the song bit in sAvailOcarinaSongFlags is turned off
// if there are no more songs remaining that it could be and the maximum position has been exceeded, then
if (sAvailOcarinaSongFlags == 0 && sStaffOcarinaPlayingPos >= sMusicStaffNumNotesPerTest) {
sIsOcarinaInputEnabled = false;
if ((sOcarinaFlags & 0x4000) && sCurOcarinaPitch == sOcarinaSongNotes[songIndex][0].pitch) {
// case never taken, this function is not called if (sOcarinaFlags & 0x4000) is set
sPrevOcarinaWithMusicStaffFlags = sOcarinaFlags;
}
sOcarinaFlags = 0;
return;
}
}
if (!noNewValidInput) {
sMusicStaffPrevPitch = sCurOcarinaPitch;
sStaffOcarinaPlayingPos += staffOcarinaPlayingPosOffset + 1;
}
}
/**
* Checks for ocarina songs from user input with no music staff prompt.
* Includes ocarina actions such as free play, no warp
*/
void AudioOcarina_CheckSongsWithoutMusicStaff(void) {
u32 pitch;
u8 i;
u8 j;
u8 k;
if (CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_L) &&
CHECK_BTN_ANY(sOcarinaInputButtonCur, sOcarinaAllowedButtonMask)) {
AudioOcarina_Start((u16)sOcarinaFlags);
return;
}
AudioOcarina_CheckIfStartedSong();
if (!sOcarinaHasStartedSong) {
return;
}
if ((sPrevOcarinaPitch != sCurOcarinaPitch) && (sCurOcarinaPitch != OCARINA_PITCH_NONE)) {
sStaffOcarinaPlayingPos++;
if (sStaffOcarinaPlayingPos > ARRAY_COUNT(sCurOcarinaSongWithoutMusicStaff)) {
sStaffOcarinaPlayingPos = 1;
}
if (sOcarinaWithoutMusicStaffPos == 8) {
for (i = 0; i < 7; i++) {
sCurOcarinaSongWithoutMusicStaff[i] = sCurOcarinaSongWithoutMusicStaff[i + 1];
}
} else {
sOcarinaWithoutMusicStaffPos++;
}
if (ABS_ALT(sCurOcarinaBendIndex) > 20) {
sCurOcarinaSongWithoutMusicStaff[sOcarinaWithoutMusicStaffPos - 1] = OCARINA_PITCH_NONE;
} else {
sCurOcarinaSongWithoutMusicStaff[sOcarinaWithoutMusicStaffPos - 1] = sCurOcarinaPitch;
}
// This nested for-loop tests to see if the notes from the ocarina are identical
// to any of the songIndex from sFirstOcarinaSongIndex to sLastOcarinaSongIndex
// Loop through each of the songs
for (i = sFirstOcarinaSongIndex; i < sLastOcarinaSongIndex; i++) {
// Checks to see if the song is available to be played
if (sAvailOcarinaSongFlags & (u16)(1 << i)) {
for (j = 0, k = 0; j < gOcarinaSongButtons[i].numButtons && k == 0 &&
sOcarinaWithoutMusicStaffPos >= gOcarinaSongButtons[i].numButtons;) {
pitch = sCurOcarinaSongWithoutMusicStaff[sOcarinaWithoutMusicStaffPos -
gOcarinaSongButtons[i].numButtons + j];
if (pitch == sButtonToPitchMap[gOcarinaSongButtons[i].buttonsIndex[j]]) {
j++;
} else {
k++;
}
}
// This conditional is true if songIndex = i is detected
if (j == gOcarinaSongButtons[i].numButtons) {
sPlayedOcarinaSongIndexPlusOne = i + 1;
sIsOcarinaInputEnabled = false;
sOcarinaFlags = 0;
}
}
}
}
}
// This unused argument is used in Majora's Mask as a u8
void AudioOcarina_PlayControllerInput(u8 unused) {
u32 ocarinaBtnsHeld;
// Prevents two different ocarina notes from being played on two consecutive frames
if ((sOcarinaFlags != 0) && (sOcarinaDropInputTimer != 0)) {
sOcarinaDropInputTimer--;
return;
}
// Ensures the button pressed to start the ocarina does not also play an ocarina note
if ((sOcarinaInputButtonStart == 0) || ((sOcarinaInputButtonStart & sOcarinaAllowedButtonMask) !=
(sOcarinaInputButtonCur & sOcarinaAllowedButtonMask))) {
sOcarinaInputButtonStart = 0;
if (1) {}
sCurOcarinaPitch = OCARINA_PITCH_NONE;
sCurOcarinaButtonIndex = OCARINA_BTN_INVALID;
ocarinaBtnsHeld = (sOcarinaInputButtonCur & sOcarinaAllowedButtonMask) &
(sOcarinaInputButtonPrev & sOcarinaAllowedButtonMask);
if (!(sOcarinaInputButtonPress & ocarinaBtnsHeld) && (sOcarinaInputButtonCur != 0)) {
sOcarinaInputButtonPress = sOcarinaInputButtonCur;
} else {
sOcarinaInputButtonPress &= ocarinaBtnsHeld;
}
// Interprets and transforms controller input into ocarina buttons and notes
if (CHECK_BTN_ANY(sOcarinaInputButtonPress, sOcarinaAButtonMap)) {
osSyncPrintf("Presss NA_KEY_D4 %08x\n", sOcarinaAButtonMap);
sCurOcarinaPitch = OCARINA_PITCH_D4;
sCurOcarinaButtonIndex = OCARINA_BTN_A;
} else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, sOcarinaCDownButtonMap)) {
osSyncPrintf("Presss NA_KEY_F4 %08x\n", sOcarinaCDownButtonMap);
sCurOcarinaPitch = OCARINA_PITCH_F4;
sCurOcarinaButtonIndex = OCARINA_BTN_C_DOWN;
} else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CRIGHT)) {
osSyncPrintf("Presss NA_KEY_A4 %08x\n", BTN_CRIGHT);
sCurOcarinaPitch = OCARINA_PITCH_A4;
sCurOcarinaButtonIndex = OCARINA_BTN_C_RIGHT;
} else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CLEFT)) {
osSyncPrintf("Presss NA_KEY_B4 %08x\n", BTN_CLEFT);
sCurOcarinaPitch = OCARINA_PITCH_B4;
sCurOcarinaButtonIndex = OCARINA_BTN_C_LEFT;
} else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, sOcarinaCUpButtonMap)) {
osSyncPrintf("Presss NA_KEY_D5 %08x\n", sOcarinaCUpButtonMap);
sCurOcarinaPitch = OCARINA_PITCH_D5;
sCurOcarinaButtonIndex = OCARINA_BTN_C_UP;
}
// Pressing the R Button will raise the pitch by 1 semitone
if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_R) &&
(sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN)) {
sCurOcarinaButtonIndex += 0x80; // Flag to resolve B Flat 4
sCurOcarinaPitch++; // Raise the pitch by 1 semitone
}
// Pressing the Z Button will lower the pitch by 1 semitone
if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_Z) &&
(sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN)) {
sCurOcarinaButtonIndex += 0x40; // Flag to resolve B Flat 4
sCurOcarinaPitch--; // Lower the pitch by 1 semitone
}
if (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN) {
// Bend the pitch of the note based on y control stick
sCurOcarinaBendIndex = sOcarinaInputStickRel.y;
sCurOcarinaBendFreq = AudioOcarina_BendPitchTwoSemitones(sCurOcarinaBendIndex);
// Add vibrato of the ocarina note based on the x control stick
sCurOcarinaVibrato = ABS_ALT(sOcarinaInputStickRel.x) >> 2;
// Sets vibrato to io port 6
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sCurOcarinaVibrato);
} else {
// no bending or vibrato for recording state OCARINA_RECORD_SCARECROW_SPAWN
sCurOcarinaBendIndex = 0;
sCurOcarinaBendFreq = 1.0f; // No bend
}
// Processes new and valid notes
if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && (sPrevOcarinaPitch != sCurOcarinaPitch)) {
// Sets ocarina instrument Id to channelIdx io port 7, which is used
// as an index in seq 0 to get the true instrument Id
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7, sOcarinaInstrumentId - 1);
// Sets pitch to io port 5
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5, sCurOcarinaPitch);
Audio_PlaySoundGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sCurOcarinaBendFreq, &sRelativeOcarinaVolume,
&gSfxDefaultReverb);
} else if ((sPrevOcarinaPitch != OCARINA_PITCH_NONE) && (sCurOcarinaPitch == OCARINA_PITCH_NONE)) {
// Stops ocarina sound when transitioning from playing to not playing a note
Audio_StopSfxById(NA_SE_OC_OCARINA);
}
}
}
/**
* Directly enable the ocarina to receive input without
* properly resetting it based on an ocarina instrument id
* Unused.
*/
void AudioOcarina_EnableInput(u8 inputEnabled) {
sIsOcarinaInputEnabled = inputEnabled;
}
/**
* Resets ocarina properties based on the ocarina instrument id
* If ocarina instrument id is "OCARINA_INSTRUMENT_OFF", turn off the ocarina
* For all ocarina instrument ids, turn the ocarina on with the instrument id
*/
void AudioOcarina_SetInstrument(u8 ocarinaInstrumentId) {
if (sOcarinaInstrumentId == ocarinaInstrumentId) {
return;
}
Audio_SeqCmd8(SEQ_PLAYER_SFX, 1, SFX_CHANNEL_OCARINA, ocarinaInstrumentId);
sOcarinaInstrumentId = ocarinaInstrumentId;
if (ocarinaInstrumentId == OCARINA_INSTRUMENT_OFF) {
sOcarinaInputButtonCur = 0;
sOcarinaInputButtonPrev = 0;
sOcarinaInputButtonPress = 0;
sOcarinaInputButtonStart = 0xFFFF;
AudioOcarina_PlayControllerInput(false);
Audio_StopSfxById(NA_SE_OC_OCARINA);
Audio_SetSoundBanksMute(0);
sPlaybackState = 0;
sPlaybackStaffPos = 0;
sIsOcarinaInputEnabled = false;
sOcarinaFlags = 0;
// return to full volume for players 0 and 3 (background bgm) after ocarina is finished
Audio_ClearBGMMute(SFX_CHANNEL_OCARINA);
} else {
sOcarinaInputButtonCur = 0;
AudioOcarina_ReadControllerInput();
// Store button used to turn on ocarina
sOcarinaInputButtonStart = sOcarinaInputButtonCur;
// lowers volumes of players 0 and 3 (background bgm) while playing ocarina
Audio_QueueSeqCmdMute(SFX_CHANNEL_OCARINA);
}
}
void AudioOcarina_SetPlaybackSong(s8 songIndexPlusOne, s8 playbackState) {
if (songIndexPlusOne == 0) {
sPlaybackState = 0;
Audio_StopSfxById(NA_SE_OC_OCARINA);
return;
}
if (songIndexPlusOne < (OCARINA_SONG_SCARECROW_LONG + 1)) {
sPlaybackSong = sOcarinaSongNotes[songIndexPlusOne - 1];
} else {
sPlaybackSong = sScarecrowsLongSongNotes;
}
sPlaybackState = playbackState;
sPlaybackNoteTimer = 0;
sPlaybackPitch = OCARINA_PITCH_NONE;
sPlaybackNotePos = 0;
sPlaybackStaffPos = 0;
while (sPlaybackSong[sPlaybackNotePos].pitch == OCARINA_PITCH_NONE) {
sPlaybackNotePos++;
}
}
/**
* Play a song with the ocarina to the user that is
* based on OcarinaNote data and not user input
*/
void AudioOcarina_PlaybackSong(void) {
u32 noteTimerStep;
u32 nextNoteTimerStep;
if (sPlaybackState == 0) {
return;
}
if (sPlaybackStaffPos == 0) {
noteTimerStep = 3;
} else {
noteTimerStep = sOcarinaUpdateTaskStart - sOcarinaPlaybackTaskStart;
}
if (noteTimerStep < sPlaybackNoteTimer) {
sPlaybackNoteTimer -= noteTimerStep;
} else {
nextNoteTimerStep = noteTimerStep - sPlaybackNoteTimer;
sPlaybackNoteTimer = 0;
}
if (sPlaybackNoteTimer == 0) {
sPlaybackNoteTimer = sPlaybackSong[sPlaybackNotePos].length;
if (sPlaybackNotePos == 1) {
sPlaybackNoteTimer++;
}
if (sPlaybackNoteTimer == 0) {
sPlaybackState--;
if (sPlaybackState != 0) {
sPlaybackNotePos = 0;
sPlaybackStaffPos = 0;
sPlaybackPitch = OCARINA_PITCH_NONE;
} else {
Audio_StopSfxById(NA_SE_OC_OCARINA);
}
return;
} else {
sPlaybackNoteTimer -= nextNoteTimerStep;
}
// Update volume
if (sNotePlaybackVolume != sPlaybackSong[sPlaybackNotePos].volume) {
sNotePlaybackVolume = sPlaybackSong[sPlaybackNotePos].volume;
sRelativeNotePlaybackVolume = sNotePlaybackVolume / 127.0f;
}
// Update vibrato
if (sNotePlaybackVibrato != sPlaybackSong[sPlaybackNotePos].vibrato) {
sNotePlaybackVibrato = sPlaybackSong[sPlaybackNotePos].vibrato;
// Sets vibrato to io port 6
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sNotePlaybackVibrato);
}
// Update bend
if (sNotePlaybackBend != sPlaybackSong[sPlaybackNotePos].bend) {
sNotePlaybackBend = sPlaybackSong[sPlaybackNotePos].bend;
sRelativeNotePlaybackBend = AudioOcarina_BendPitchTwoSemitones(sNotePlaybackBend);
}
// No changes in volume, vibrato, or bend between notes
if ((sPlaybackSong[sPlaybackNotePos].volume == sPlaybackSong[sPlaybackNotePos - 1].volume &&
(sPlaybackSong[sPlaybackNotePos].vibrato == sPlaybackSong[sPlaybackNotePos - 1].vibrato) &&
(sPlaybackSong[sPlaybackNotePos].bend == sPlaybackSong[sPlaybackNotePos - 1].bend))) {
sPlaybackPitch = 0xFE;
}
if (sPlaybackPitch != sPlaybackSong[sPlaybackNotePos].pitch) {
u8 pitch = sPlaybackSong[sPlaybackNotePos].pitch;
// As bFlat4 is exactly in the middle of notes B & A, a flag is
// added to the pitch to resolve which button to map Bflat4 to
if (pitch == OCARINA_PITCH_BFLAT4) {
sPlaybackPitch = pitch + sPlaybackSong[sPlaybackNotePos].bFlat4Flag;
} else {
sPlaybackPitch = pitch;
}
if (sPlaybackPitch != OCARINA_PITCH_NONE) {
sPlaybackStaffPos++;
// Sets ocarina instrument Id to channelIdx io port 7, which is used
// as an index in seq 0 to get the true instrument Id
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7,
sOcarinaInstrumentId - 1);
// Sets sPlaybackPitch to channelIdx io port 5
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5,
sPlaybackPitch & 0x3F);
Audio_PlaySoundGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sRelativeNotePlaybackBend,
&sRelativeNotePlaybackVolume, &gSfxDefaultReverb);
} else {
Audio_StopSfxById(NA_SE_OC_OCARINA);
}
}
sPlaybackNotePos++;
}
}
void AudioOcarina_SetRecordingSong(u8 isRecordingComplete) {
u16 i;
u16 i2;
u16 pad;
u8 pitch;
OcarinaNote* note;
u8 j;
u8 k;
s32 t;
OcarinaNote* recordedSong;
if (sRecordingState == OCARINA_RECORD_SCARECROW_LONG) {
recordedSong = gScarecrowLongSongPtr;
} else {
/**
* OCARINA_RECORD_SCARECROW_SPAWN
*
* The notes for scarecrows spawn song are first recorded into the ocarina memory
* game address to act as a buffer. That way, if a new scarecrow spawn song is
* rejected, the previous scarecrow spawn song is not overwritten. If the scarecrow
* spawn song is accepted, then the notes are copied over to the scarecrow spawn
* song address
*/
recordedSong = sMemoryGameSongPtr;
}
recordedSong[sRecordSongPos].pitch = sRecordOcarinaPitch;
recordedSong[sRecordSongPos].length = sOcarinaUpdateTaskStart - sOcarinaRecordTaskStart;
recordedSong[sRecordSongPos].volume = sRecordOcarinaVolume;
recordedSong[sRecordSongPos].vibrato = sRecordOcarinaVibrato;
recordedSong[sRecordSongPos].bend = sRecordOcarinaBendIndex;
recordedSong[sRecordSongPos].bFlat4Flag = sRecordOcarinaButtonIndex & 0xC0;
sRecordOcarinaPitch = sCurOcarinaPitch;
sRecordOcarinaVolume = sCurOcarinaVolume;
sRecordOcarinaVibrato = sCurOcarinaVibrato;
sRecordOcarinaBendIndex = sCurOcarinaBendIndex;
sRecordOcarinaButtonIndex = sCurOcarinaButtonIndex;
sRecordSongPos++;
if ((sRecordSongPos != (ARRAY_COUNT(sScarecrowsLongSongNotes) - 1)) && !isRecordingComplete) {
// Continue recording
return;
}
// Recording is complete
i = sRecordSongPos;
pitch = OCARINA_PITCH_NONE;
while (i != 0 && pitch == OCARINA_PITCH_NONE) {
i--;
pitch = recordedSong[i].pitch;
}
if (1) {}
if (sRecordSongPos != (i + 1)) {
sRecordSongPos = i + 2;
recordedSong[sRecordSongPos - 1].length = 0;
}
recordedSong[sRecordSongPos].length = 0;
if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) {
if (sStaffOcarinaPlayingPos >= 8) {
for (i = 0; i < sRecordSongPos; i++) {
recordedSong[i] = recordedSong[i + 1];
}
// Copies Notes from buffer into scarecrows spawn buttons to be tested for acceptance or rejection
AudioOcarina_MapNotesToScarecrowButtons(OCARINA_SONG_MEMORY_GAME);
// Loop through each of the songs
for (i = 0; i < OCARINA_SONG_SCARECROW_SPAWN; i++) {
// Loops through all possible starting indices
for (j = 0; j < 9 - gOcarinaSongButtons[i].numButtons; j++) {
// Loops through the notes of song i
for (k = 0; k < gOcarinaSongButtons[i].numButtons && k + j < 8 &&
gOcarinaSongButtons[i].buttonsIndex[k] ==
gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonsIndex[k + j];
k++) {
;
}
// This conditional is true if the recorded song contains a reserved song
if (k == gOcarinaSongButtons[i].numButtons) {
sRecordingState = OCARINA_RECORD_REJECTED;
sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume = 0xFF;
return;
}
}
}
// Counts how many times a note is repeated
i = 1;
while (i < 8) {
if (gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonsIndex[0] !=
gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonsIndex[i]) {
i = 9; // break
} else {
i++;
}
}
// This condition is true if all 8 notes are the same pitch
if (i == 8) {
sRecordingState = OCARINA_RECORD_REJECTED;
sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume = 0xFF;
return;
}
// The scarecrow spawn song is accepted and copied from the buffer to the scarecrow spawn notes
for (i = 0; i < sRecordSongPos; i++) {
sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][i] = sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][i];
}
sIsOcarinaInputEnabled = false;
} else {
sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume = 0xFF;
}
}
sRecordingState = OCARINA_RECORD_OFF;
}
/**
* recordingState = OCARINA_RECORD_OFF, end
* recordingState = OCARINA_RECORD_SCARECROW_LONG, start long scarecrows song
* recordingState = OCARINA_RECORD_SCARECROW_SPAWN, start spawn scarecrows song
*/
void AudioOcarina_SetRecordingState(u8 recordingState) {
if ((u32)recordingState == sRecordingState) {
return;
}
if (recordingState != OCARINA_RECORD_OFF) {
sOcarinaRecordTaskStart = sOcarinaUpdateTaskStart;
sRecordOcarinaPitch = OCARINA_PITCH_NONE;
sRecordOcarinaVolume = 0x57;
sRecordOcarinaVibrato = 0;
sRecordOcarinaBendIndex = 0;
sRecordOcarinaButtonIndex = 0;
sRecordSongPos = 0;
sIsOcarinaInputEnabled = true;
sStaffOcarinaPlayingPos = 0;
sScarecrowsLongSongSecondNote = sScarecrowsLongSongNotes[1];
} else {
if (sRecordSongPos == 0) {
sScarecrowsLongSongNotes[1] = sScarecrowsLongSongSecondNote;
} else {
if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) {
sStaffOcarinaPlayingPos = 1;
}
AudioOcarina_SetRecordingSong(true);
}
sIsOcarinaInputEnabled = false;
sStaffOcarinaPlayingPos = 0;
}
sRecordingState = recordingState;
}
void AudioOcarina_UpdateRecordingStaff(void) {
sRecordingStaff.state = sRecordingState;
sRecordingStaff.pos = sStaffOcarinaPlayingPos;
if (sRecordingState == OCARINA_RECORD_REJECTED) {
sRecordingState = OCARINA_RECORD_OFF;
}
}
void AudioOcarina_UpdatePlayingStaff(void) {
sPlayingStaff.buttonIndex = sCurOcarinaButtonIndex & 0x3F;
sPlayingStaff.state = AudioOcarina_GetPlayingState();
sPlayingStaff.pos = sStaffOcarinaPlayingPos;
}
void AudioOcarina_UpdatePlaybackStaff(void) {
if ((sPlaybackPitch & 0x3F) <= OCARINA_PITCH_EFLAT5) {
sPlaybackStaff.buttonIndex = AudioOcarina_MapNoteToButton(sPlaybackPitch);
}
sPlaybackStaff.state = sPlaybackState;
if (sPlaybackSong != sScarecrowsLongSongNotes) {
sPlaybackStaff.pos = sPlaybackStaffPos;
} else if (sPlaybackStaffPos == 0) {
sPlaybackStaff.pos = 0;
} else {
sPlaybackStaff.pos = ((sPlaybackStaffPos - 1) % 8) + 1;
}
}
OcarinaStaff* AudioOcarina_GetRecordingStaff(void) {
return &sRecordingStaff;
}
OcarinaStaff* AudioOcarina_GetPlayingStaff(void) {
if (sPlayingStaff.state < 0xFE) {
sOcarinaFlags = 0;
}
return &sPlayingStaff;
}
OcarinaStaff* AudioOcarina_GetPlaybackStaff(void) {
return &sPlaybackStaff;
}
void AudioOcarina_RecordSong(void) {
s32 noteChanged;
if ((sRecordingState != OCARINA_RECORD_OFF) && ((sOcarinaUpdateTaskStart - sOcarinaRecordTaskStart) >= 3)) {
noteChanged = false;
if (sRecordOcarinaPitch != sCurOcarinaPitch) {
if (sCurOcarinaPitch != OCARINA_PITCH_NONE) {
sRecordingStaff.buttonIndex = sCurOcarinaButtonIndex & 0x3F;
sStaffOcarinaPlayingPos++;
} else if ((sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) && (sStaffOcarinaPlayingPos == 8)) {
AudioOcarina_SetRecordingSong(true);
return;
}
if (sStaffOcarinaPlayingPos > 8) {
if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) {
// notes played are over 8 and in recording mode.
AudioOcarina_SetRecordingSong(true);
return;
}
sStaffOcarinaPlayingPos = 1;
}
noteChanged = true;
} else if (sRecordOcarinaVolume != sCurOcarinaVolume) {
noteChanged = true;
} else if (sRecordOcarinaVibrato != sCurOcarinaVibrato) {
noteChanged = true;
} else if (sRecordOcarinaBendIndex != sCurOcarinaBendIndex) {
noteChanged = true;
}
if (noteChanged) {
AudioOcarina_SetRecordingSong(false);
sOcarinaRecordTaskStart = sOcarinaUpdateTaskStart;
}
}
}
void AudioOcarina_MemoryGameInit(u8 minigameRound) {
u8 i;
if (minigameRound > 2) {
minigameRound = 2;
}
sOcaMemoryGameAppendPos = 0;
sOcaMemoryGameEndPos = sOcaMemoryGameNumNotes[minigameRound];
for (i = 0; i < 3; i++) {
AudioOcarina_MemoryGameNextNote();
}
}
s32 AudioOcarina_MemoryGameNextNote(void) {
u32 randomButtonIndex;
u8 randomPitch;
if (sOcaMemoryGameAppendPos == sOcaMemoryGameEndPos) {
return 1;
}
randomButtonIndex = Audio_NextRandom();
randomPitch = sButtonToPitchMap[randomButtonIndex % 5];
if (sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos - 1].pitch == randomPitch) {
randomPitch = sButtonToPitchMap[(randomButtonIndex + 1) % 5];
}
sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].pitch = randomPitch;
sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].length = 45;
sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].volume = 0x50;
sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].vibrato = 0;
sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].bend = 0;
sOcaMemoryGameAppendPos++;
sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].pitch = OCARINA_PITCH_NONE;
sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].length = 0;
sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos + 1].pitch = OCARINA_PITCH_NONE;
sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos + 1].length = 0;
if (1) {}
return 0;
}
void AudioOcarina_Update(void) {
sOcarinaUpdateTaskStart = gAudioContext.totalTaskCount;
if (sOcarinaInstrumentId != OCARINA_INSTRUMENT_OFF) {
if (sIsOcarinaInputEnabled == true) {
AudioOcarina_ReadControllerInput();
}
if ((sPlaybackState == 0) && (sIsOcarinaInputEnabled == true)) {
AudioOcarina_PlayControllerInput(false);
}
if (sOcarinaFlags != 0) {
if (sOcarinaFlags & 0x4000) {
AudioOcarina_CheckSongsWithoutMusicStaff();
} else {
AudioOcarina_CheckSongsWithMusicStaff();
}
}
AudioOcarina_PlaybackSong();
sOcarinaPlaybackTaskStart = sOcarinaUpdateTaskStart;
if (sPlaybackState == 0) {
AudioOcarina_RecordSong();
}
if ((sOcarinaFlags != 0) && (sPrevOcarinaPitch != sCurOcarinaPitch)) {
sOcarinaDropInputTimer = 1; // Drops ocarina input for 1 frame
}
sPrevOcarinaPitch = sCurOcarinaPitch;
}
AudioOcarina_UpdatePlayingStaff();
AudioOcarina_UpdatePlaybackStaff();
AudioOcarina_UpdateRecordingStaff();
}
void AudioOcarina_PlayLongScarecrowAfterCredits(void) {
static u8 sScarecrowAfterCreditsState = 0;
static u8 sScarecrowAfterCreditsIntrumentId = OCARINA_INSTRUMENT_DEFAULT;
static u16 sScarecrowAfterCreditsTimer = 1200;
switch (sScarecrowAfterCreditsState) {
case 0:
if (sScarecrowAfterCreditsTimer-- == 0) {
if (sScarecrowAfterCreditsIntrumentId < OCARINA_INSTRUMENT_MAX) {
// set next ocarina instrument and restart
sScarecrowAfterCreditsState++;
} else {
// finished
sScarecrowAfterCreditsState = 3;
AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF);
}
sScarecrowAfterCreditsTimer = 1200;
}
break;
case 1:
Audio_SetSoundBanksMute(0);
AudioOcarina_SetInstrument(sScarecrowAfterCreditsIntrumentId);
AudioOcarina_SetPlaybackSong(OCARINA_SONG_SCARECROW_LONG + 1, 1);
sScarecrowAfterCreditsIntrumentId++;
sScarecrowAfterCreditsState++;
break;
case 2:
if (AudioOcarina_GetPlaybackStaff()->state == 0) {
sScarecrowAfterCreditsState = 0;
}
break;
}
}
void AudioOcarina_ResetStaffs(void) {
sPlayingStaff.buttonIndex = OCARINA_BTN_INVALID;
sPlayingStaff.state = 0xFF;
sPlayingStaff.pos = 0;
sPlaybackStaff.buttonIndex = OCARINA_BTN_INVALID;
sPlaybackStaff.state = 0;
sPlaybackStaff.pos = 0;
sRecordingStaff.buttonIndex = OCARINA_BTN_INVALID;
sRecordingStaff.state = OCARINA_RECORD_REJECTED;
sRecordingStaff.pos = 0;
sOcarinaDropInputTimer = 0;
}
f32 D_80131C8C = 0.0f;
// =========== Audio Debugging ===========
extern u16 gAudioSfxSwapSource[];
extern u16 gAudioSfxSwapTarget[];
extern u8 gAudioSfxSwapMode[];
extern u8 gAudioSfxSwapOff;
extern u8 D_801333F0;
u32 sDebugPadHold;
u32 sDebugPadBtnLast;
u32 sDebugPadPress;
s32 sAudioUpdateTaskStart;
s32 sAudioUpdateTaskEnd;
f32 sAudioUpdateDuration = 0.0f;
f32 sAudioUpdateDurationMax = 0.0f;
u8 sAudioDebugEverOpened = 0;
u8 sAudioSfxMuted = 0;
u8 sAudioDebugPage = 0;
u8 sAudioSndContSel = 0;
u8 sAudioDebugTextColor = 7;
char sAudioDebugPageNames[15][23] = {
"Non",
"Sound Control",
"Spec Info",
"Heap Info",
"Grp Track Info",
"Sub Track Info",
"Channel Info",
"Interface Info",
"SE Flag Swap",
"Block Change BGM",
"Natural Sound Control",
"Ocarina Test",
"SE Parameter Change",
"Scroll Print",
"Free Area",
};
u16 sAudioSndContWork[11] = { 0 };
u16 sAudioSndContWorkLims[11] = { 128, 128, 7, 512, 4, 2, 16, 32, 2, 2, 2 };
char sSoundBankNames[7][11] = { "PLAYER", "ITEM", "ENVIROMENT", "ENEMY", "SYSTEM", "OCARINA", "VOICE" };
char sSoundModeNames[5][10] = { "W-STEREO", "HEADPHONE", "3D SOUND", "MONO", "" };
s8 sAudioIntInfoX = 0;
s8 sAudioIntInfoY = 0;
s8 sAudioIntInfoSel = 0;
s8 sAudioIntInfoBankPage[7] = { 0, 0, 2, 2, 0, 0, 0 };
u8 sAudioScrPrtSel = 0;
u8 sAudioScrPrtInd = 0;
u8 sAudioScrPrtOverflow = 0;
s8 sAudioScrPrtX = 26;
s8 sAudioScrPrtY = 1;
u8 sAudioScrPrtWork[11] = { 1, 19, 6, 0, 0, 0, 0, 0, 0, 0, 1 };
u8 sAudioScrPrtWorkLims[11] = { 2, SCROLL_PRINT_BUF_SIZE, 8, 2, 2, 2, 2, 2, 2, 2, 2 };
u8 sAudioSubTrackInfoSpec = 0;
u8 sAudioSfxSwapIsEditing = 0;
u8 sAudioSfxSwapSel = 0;
u8 sAudioSfxSwapNibbleSel = 0;
char sAudioSfxSwapModeNames[2][5] = { "SWAP", "ADD" };
u8 sAudioSfxParamChgSel = 0;
u8 sAudioSfxParamChgBitSel = 0;
u16 sAudioSfxParamChgWork[4] = { 0 };
u8 sAudioSubTrackInfoPlayerSel = SEQ_PLAYER_BGM_MAIN;
u8 sAudioSubTrackInfoChannelSel = 0;
u8 sSeqPlayerPeakNumLayers[20] = { 0 };
char sAudioSceneNames[3][2] = { "A", "S", "X" };
u8 sAudioBlkChgBgmWork[2] = { 0 };
u8 sAudioBlkChgBgmSel = 0;
char sBoolStrs[3][5] = { "OFF", "ON", "STBY" };
u8 sAudioNatureFailed = false;
u8 sPeakNumNotes = 0;
void AudioDebug_SetInput(void) {
Input inputs[4];
u32 btn;
PadMgr_RequestPadData(&gPadMgr, inputs, 0);
btn = inputs[3].cur.button;
sDebugPadHold = btn & 0xFFFF;
sDebugPadPress = (btn ^ sDebugPadBtnLast) & btn;
sDebugPadBtnLast = btn;
}
char* AudioDebug_ToStringBinary(u32 num, u8 bits) {
u8 i;
u32 flg = 1;
for (i = 0; i < bits; flg *= 2, i++) {
if (num & flg) {
sBinToStrBuf[bits - i - 1] = '1';
} else {
sBinToStrBuf[bits - i - 1] = '0';
}
}
sBinToStrBuf[bits] = '\0';
return sBinToStrBuf;
}
void AudioDebug_Draw(GfxPrint* printer) {
s32 pad[3];
u8 i;
u8 j;
u8 ctr;
u8 ctr2;
s8 k;
s8 k2;
s8 ind;
u8 numEnabledNotes = 0;
char digitStr[2] = "1";
#define SETCOL_COMMON(v, r, g, b) \
GfxPrint_SetColor(printer, ((v & 4) >> 2) * (r), ((v & 2) >> 1) * (g), (v & 1) * (b), 255)
#define SETCOL(r, g, b) SETCOL_COMMON(sAudioDebugTextColor, r, g, b)
#define SETCOL_SCROLLPRINT(r, g, b) SETCOL_COMMON(sAudioScrPrtWork[2], r, g, b)
sAudioDebugEverOpened = true;
GfxPrint_SetPos(printer, 3, 2);
SETCOL(255, 255, 255);
GfxPrint_Printf(printer, "Audio Debug Mode");
GfxPrint_SetPos(printer, 3, 3);
GfxPrint_Printf(printer, "- %s -", sAudioDebugPageNames[sAudioDebugPage]);
for (i = 0; i < gAudioSpecs[gAudioSpecId].numNotes; i++) {
if (gAudioContext.notes[i].noteSubEu.bitField0.enabled == 1) {
numEnabledNotes++;
}
}
if (sPeakNumNotes < numEnabledNotes) {
sPeakNumNotes = numEnabledNotes;
}
if (sAudioSpecPeakNumNotes[gAudioSpecId] < numEnabledNotes) {
sAudioSpecPeakNumNotes[gAudioSpecId] = numEnabledNotes;
}
if (sAudioScrPrtWork[0] != 0) {
GfxPrint_SetPos(printer, sAudioScrPrtX, sAudioScrPrtY);
SETCOL_SCROLLPRINT(200, 200, 200);
GfxPrint_Printf(printer, "Audio ScrPrt");
ind = sAudioScrPrtInd;
for (k = 0; k < sAudioScrPrtWork[1] + 1; k++) {
if (ind == 0) {
if (sAudioScrPrtOverflow == 1) {
ind = SCROLL_PRINT_BUF_SIZE - 1;
} else {
k = sAudioScrPrtWork[1] + 1; // "break;"
}
} else {
ind--;
}
if (k != sAudioScrPrtWork[1] + 1) {
if ((ind % 5) != 0) {
SETCOL_SCROLLPRINT(180, 180, 180);
} else {
SETCOL_SCROLLPRINT(120, 120, 120);
}
GfxPrint_SetPos(printer, 2 + sAudioScrPrtX, sAudioScrPrtY + sAudioScrPrtWork[1] + 1 - k);
GfxPrint_Printf(printer, "%s", sAudioScrPrtBuf[ind].str);
GfxPrint_SetPos(printer, 7 + sAudioScrPrtX, sAudioScrPrtY + sAudioScrPrtWork[1] + 1 - k);
GfxPrint_Printf(printer, "%04X", sAudioScrPrtBuf[ind].num);
}
}
}
switch (sAudioDebugPage) {
case PAGE_NON:
GfxPrint_SetPos(printer, 3, 4);
SETCOL(255, 64, 64);
GfxPrint_Printf(printer, "BGM CANCEL:%s", sBoolStrs[sAudioSndContWork[5]]);
GfxPrint_SetPos(printer, 3, 5);
GfxPrint_Printf(printer, "SE MUTE:%s", sBoolStrs[sAudioSfxMuted]);
GfxPrint_SetPos(printer, 18, 4);
SETCOL(255, 255, 255);
GfxPrint_Printf(printer, "PUSH CONT-4 A-BTN");
ind = (s8)sAudioSndContWork[2];
i = gSoundBanks[ind][0].next;
j = 0;
SETCOL(255, 255, 255);
GfxPrint_SetPos(printer, 3, 6);
GfxPrint_Printf(printer, "SE HANDLE:%s", sSoundBankNames[ind]);
while (i != 0xFF) {
GfxPrint_SetPos(printer, 3, 7 + j++);
GfxPrint_Printf(printer, "%02x %04x %02x %08x", i, gSoundBanks[ind][i].sfxId, gSoundBanks[ind][i].state,
gSoundBanks[ind][i].priority);
i = gSoundBanks[ind][i].next;
}
break;
case PAGE_SOUND_CONTROL:
GfxPrint_SetPos(printer, 2, 4 + sAudioSndContSel);
SETCOL(127, 255, 127);
GfxPrint_Printf(printer, "*");
SETCOL(255, 255, 255);
GfxPrint_SetPos(printer, 3, 4);
GfxPrint_Printf(printer, "Seq 0 : %2x", sAudioSndContWork[0]);
GfxPrint_SetPos(printer, 3, 5);
GfxPrint_Printf(printer, "Seq 1 : %2x", sAudioSndContWork[1]);
GfxPrint_SetPos(printer, 3, 6);
GfxPrint_Printf(printer, "SE HD : %2x %s", sAudioSndContWork[2], sSoundBankNames[sAudioSndContWork[2]]);
GfxPrint_SetPos(printer, 3, 7);
GfxPrint_Printf(printer, "SE No. :%3x", sAudioSndContWork[3]);
GfxPrint_SetPos(printer, 3, 8);
GfxPrint_Printf(printer, "S-Out : %2x %s", sAudioSndContWork[4], sSoundModeNames[sAudioSndContWork[4]]);
GfxPrint_SetPos(printer, 3, 9);
GfxPrint_Printf(printer, "BGM Ent: %2x", sAudioSndContWork[5]);
GfxPrint_SetPos(printer, 3, 10);
GfxPrint_Printf(printer, "Spec : %2x", sAudioSndContWork[6]);
GfxPrint_SetPos(printer, 3, 11);
GfxPrint_Printf(printer, "Na Snd : %2x", sAudioSndContWork[7]);
GfxPrint_SetPos(printer, 3, 12);
GfxPrint_Printf(printer, "Cam Wt : %s", sBoolStrs[sAudioSndContWork[8]]);
GfxPrint_SetPos(printer, 3, 13);
GfxPrint_Printf(printer, "Lnk Wt : %s", sBoolStrs[sAudioSndContWork[9]]);
GfxPrint_SetPos(printer, 3, 14);
GfxPrint_Printf(printer, "SE Ent : %2x", sAudioSndContWork[10]);
break;
case PAGE_INTERFACE_INFO:
ind = 0;
for (k = 0; k < 7; k++) {
if (k == sAudioIntInfoSel) {
SETCOL(255, 127, 127);
} else {
SETCOL(255, 255, 255);
}
GfxPrint_SetPos(printer, 2 + sAudioIntInfoX, 4 + ind + sAudioIntInfoY);
GfxPrint_Printf(printer, "%s <%d>", sSoundBankNames[k], sAudioIntInfoBankPage[k]);
for (k2 = 0; k2 < gChannelsPerBank[gSfxChannelLayout][k]; k2++) {
#define entryIndex (gActiveSounds[k][k2].entryIndex)
#define entry (&gSoundBanks[k][entryIndex])
#define chan (gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[entry->channelIdx])
GfxPrint_SetPos(printer, 2 + sAudioIntInfoX, 5 + ind + sAudioIntInfoY);
if (sAudioIntInfoBankPage[k] == 1) {
if ((entryIndex != 0xFF) &&
((entry->state == SFX_STATE_PLAYING_1) || (entry->state == SFX_STATE_PLAYING_2))) {
GfxPrint_Printf(printer, "%2X %5d %5d %5d %02X %04X %04X", entryIndex, (s32)*entry->posX,
(s32)*entry->posY, (s32)*entry->posZ, entry->sfxImportance,
entry->sfxParams, entry->sfxId);
} else {
GfxPrint_Printf(printer, "FF ----- ----- ----- -- ---- ----");
}
} else if (sAudioIntInfoBankPage[k] == 2) {
if ((entryIndex != 0xFF) &&
((entry->state == SFX_STATE_PLAYING_1) || (entry->state == SFX_STATE_PLAYING_2))) {
GfxPrint_Printf(printer, "%2X %5d %5d %5d %3d %3d %04X", entryIndex, (s32)*entry->posX,
(s32)*entry->posY, (s32)*entry->posZ, (s32)(chan->volume * 127.1f),
chan->newPan, entry->sfxId);
} else {
GfxPrint_Printf(printer, "FF ----- ----- ----- --- --- ----");
}
} else if (sAudioIntInfoBankPage[k] == 3) {
if ((entryIndex != 0xFF) &&
((entry->state == SFX_STATE_PLAYING_1) || (entry->state == SFX_STATE_PLAYING_2))) {
GfxPrint_Printf(printer, "%2X %5d %5d %5d %3d %3d %04X", entryIndex, (s32)*entry->posX,
(s32)*entry->posY, (s32)*entry->posZ, (s32)(chan->freqScale * 100.0f),
chan->reverb, entry->sfxId);
} else {
GfxPrint_Printf(printer, "FF ----- ----- ----- --- --- ----");
}
} else if (sAudioIntInfoBankPage[k] == 4) {
if ((entryIndex != 0xFF) &&
((entry->state == SFX_STATE_PLAYING_1) || (entry->state == SFX_STATE_PLAYING_2))) {
GfxPrint_Printf(printer, "%2X %04X", entryIndex, entry->sfxId);
} else {
GfxPrint_Printf(printer, "FF ----");
}
}
#undef entryIndex
#undef entry
#undef chan
if (sAudioIntInfoBankPage[k] != 0) {
ind++;
}
}
ind++;
}
break;
case PAGE_SCROLL_PRINT:
GfxPrint_SetPos(printer, 2, 4 + sAudioScrPrtSel);
SETCOL(255, 255, 255);
GfxPrint_Printf(printer, "*");
SETCOL(255, 255, 255);
GfxPrint_SetPos(printer, 3, 4);
GfxPrint_Printf(printer, "Swicth : %d", sAudioScrPrtWork[0]);
GfxPrint_SetPos(printer, 3, 5);
GfxPrint_Printf(printer, "Lines : %d", sAudioScrPrtWork[1] + 1);
GfxPrint_SetPos(printer, 3, 6);
GfxPrint_Printf(printer, "Color : %d", sAudioScrPrtWork[2]);
GfxPrint_SetPos(printer, 3, 7);
GfxPrint_Printf(printer, "%s : %d", sSoundBankNames[0], sAudioScrPrtWork[3]);
GfxPrint_SetPos(printer, 3, 8);
GfxPrint_Printf(printer, "%s : %d", sSoundBankNames[1], sAudioScrPrtWork[4]);
GfxPrint_SetPos(printer, 3, 9);
GfxPrint_Printf(printer, "ENVRONM : %d", sAudioScrPrtWork[5]);
GfxPrint_SetPos(printer, 3, 10);
GfxPrint_Printf(printer, "%s : %d", sSoundBankNames[3], sAudioScrPrtWork[6]);
GfxPrint_SetPos(printer, 3, 11);
GfxPrint_Printf(printer, "%s : %d", sSoundBankNames[4], sAudioScrPrtWork[7]);
GfxPrint_SetPos(printer, 3, 12);
GfxPrint_Printf(printer, "%s : %d", sSoundBankNames[5], sAudioScrPrtWork[8]);
GfxPrint_SetPos(printer, 3, 13);
GfxPrint_Printf(printer, "%s : %d", sSoundBankNames[6], sAudioScrPrtWork[9]);
GfxPrint_SetPos(printer, 3, 14);
GfxPrint_Printf(printer, "SEQ ENT : %d", sAudioScrPrtWork[10]);
break;
case PAGE_SFX_SWAP:
GfxPrint_SetPos(printer, 3, 4);
SETCOL(255, 255, 255);
if (gAudioSfxSwapOff) {
GfxPrint_Printf(printer, "SWAP OFF");
}
if (sAudioSfxSwapIsEditing == 0) {
SETCOL(255, 255, 255);
} else {
SETCOL(127, 127, 127);
}
GfxPrint_SetPos(printer, 2, 6 + sAudioSfxSwapSel);
GfxPrint_Printf(printer, "*");
ctr = sAudioSfxSwapNibbleSel;
if (sAudioSfxSwapNibbleSel >= 4) {
ctr++;
}
if (sAudioSfxSwapIsEditing == 1) {
SETCOL(255, 255, 255);
GfxPrint_SetPos(printer, 3 + ctr, 5);
GfxPrint_Printf(printer, "V");
}
for (i = 0; i < 10; i++) {
if (i == sAudioSfxSwapSel) {
if (sAudioSfxSwapIsEditing == 0) {
SETCOL(192, 192, 192);
} else {
SETCOL(255, 255, 255);
}
} else if (sAudioSfxSwapIsEditing == 0) {
SETCOL(144, 144, 144);
} else {
SETCOL(96, 96, 96);
}
GfxPrint_SetPos(printer, 3, 6 + i);
GfxPrint_Printf(printer, "%04x %04x %s", gAudioSfxSwapSource[i], gAudioSfxSwapTarget[i],
sAudioSfxSwapModeNames[gAudioSfxSwapMode[i]]);
}
break;
case PAGE_SUB_TRACK_INFO:
GfxPrint_SetPos(printer, 3, 4);
SETCOL(255, 255, 255);
GfxPrint_Printf(printer, "Group Track:%d", sAudioSubTrackInfoPlayerSel);
GfxPrint_SetPos(printer, 3, 5);
GfxPrint_Printf(printer, "Sub Track :%d", sAudioSubTrackInfoChannelSel);
GfxPrint_SetPos(printer, 3, 6);
GfxPrint_Printf(printer, "TRK NO. ");
GfxPrint_SetPos(printer, 3, 7);
GfxPrint_Printf(printer, "ENTRY ");
GfxPrint_SetPos(printer, 3, 8);
GfxPrint_Printf(printer, "MUTE ");
GfxPrint_SetPos(printer, 3, 9);
GfxPrint_Printf(printer, "OPENNOTE");
ctr2 = 0;
for (i = 0; i < 16; i++) {
if (i == sAudioSubTrackInfoChannelSel) {
SETCOL(255, 255, 255);
} else {
SETCOL(200, 200, 200);
}
GfxPrint_SetPos(printer, 15 + i, 6);
GfxPrint_Printf(printer, "%1X", i);
GfxPrint_SetPos(printer, 15 + i, 7);
if (gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[i]->enabled) {
GfxPrint_Printf(printer, "O");
} else {
GfxPrint_Printf(printer, "X");
}
GfxPrint_SetPos(printer, 15 + i, 8);
if (gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[i]->stopSomething2) {
GfxPrint_Printf(printer, "O");
} else {
GfxPrint_Printf(printer, "X");
}
GfxPrint_SetPos(printer, 15 + i, 9);
ctr = 0;
for (j = 0; j < 4; j++) {
if (gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[i]->layers[j] != NULL) {
ctr++;
}
}
GfxPrint_Printf(printer, "%1X", ctr);
ctr2 += ctr;
}
SETCOL(255, 255, 255);
if (sSeqPlayerPeakNumLayers[sAudioSubTrackInfoPlayerSel] < ctr2) {
sSeqPlayerPeakNumLayers[sAudioSubTrackInfoPlayerSel] = ctr2;
}
GfxPrint_SetPos(printer, 16 + i, 9);
GfxPrint_Printf(printer, "%2d,%2d", ctr2, sSeqPlayerPeakNumLayers[sAudioSubTrackInfoPlayerSel]);
GfxPrint_SetPos(printer, 3, 11);
GfxPrint_Printf(printer, "VOL ");
GfxPrint_SetPos(printer, 3, 12);
GfxPrint_Printf(printer, "E VOL ");
GfxPrint_SetPos(printer, 3, 13);
GfxPrint_Printf(printer, "BANK ID ");
GfxPrint_SetPos(printer, 3, 14);
GfxPrint_Printf(printer, "PROG ");
GfxPrint_SetPos(printer, 3, 15);
GfxPrint_Printf(printer, "PAN ");
GfxPrint_SetPos(printer, 3, 16);
GfxPrint_Printf(printer, "PANPOW ");
GfxPrint_SetPos(printer, 3, 17);
GfxPrint_Printf(printer, "FXMIX ");
GfxPrint_SetPos(printer, 3, 18);
GfxPrint_Printf(printer, "PRIO ");
GfxPrint_SetPos(printer, 3, 19);
GfxPrint_Printf(printer, "VIB PIT ");
GfxPrint_SetPos(printer, 3, 20);
GfxPrint_Printf(printer, "VIB DEP ");
GfxPrint_SetPos(printer, 3, 21);
GfxPrint_Printf(printer, "TUNE ");
GfxPrint_SetPos(printer, 3, 22);
GfxPrint_Printf(printer, "TUNE ");
for (i = 0; i < 8; i++) {
GfxPrint_SetPos(printer, 15 + 3 * i, 22);
GfxPrint_Printf(printer, "%02X ",
(u8)gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->soundScriptIO[i]);
}
if (gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[sAudioSubTrackInfoChannelSel]->enabled) {
GfxPrint_SetPos(printer, 15, 11);
GfxPrint_Printf(printer, "%d",
(u8)(gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->volume *
127.1));
GfxPrint_SetPos(printer, 15, 12);
GfxPrint_Printf(printer, "%d",
(u8)(gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->volumeScale *
127.1));
GfxPrint_SetPos(printer, 15, 13);
GfxPrint_Printf(printer, "%X",
gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->fontId);
ctr = (u8)(gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->instOrWave);
if (ctr == 0) {
ctr2 = 0x7F;
} else if (ctr < 0x80) {
ctr2 = ctr - 1;
} else {
ctr2 = ctr;
}
GfxPrint_SetPos(printer, 15, 14);
GfxPrint_Printf(printer, "%d", ctr2);
GfxPrint_SetPos(printer, 15, 15);
GfxPrint_Printf(printer, "%d",
gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->newPan);
GfxPrint_SetPos(printer, 15, 16);
GfxPrint_Printf(printer, "%d",
gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->panChannelWeight);
GfxPrint_SetPos(printer, 15, 17);
GfxPrint_Printf(printer, "%d",
gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->reverb);
GfxPrint_SetPos(printer, 15, 18);
GfxPrint_Printf(printer, "%d",
gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->notePriority);
GfxPrint_SetPos(printer, 15, 19);
GfxPrint_Printf(printer, "%d",
(u8)(gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->vibratoRateTarget /
32));
GfxPrint_SetPos(printer, 15, 20);
GfxPrint_Printf(printer, "%d",
(u8)(gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->vibratoExtentTarget /
8));
GfxPrint_SetPos(printer, 15, 21);
GfxPrint_Printf(printer, "%d",
(u16)(gAudioContext.seqPlayers[sAudioSubTrackInfoPlayerSel]
.channels[sAudioSubTrackInfoChannelSel]
->freqScale *
100));
}
break;
case PAGE_HEAP_INFO:
SETCOL(255, 255, 255);
GfxPrint_SetPos(printer, 3, 4);
GfxPrint_Printf(printer, "TOTAL %d", D_8014A6C4.heapSize);
GfxPrint_SetPos(printer, 3, 5);
GfxPrint_Printf(printer, "DRIVER %05X / %05X",
gAudioContext.notesAndBuffersPool.cur - gAudioContext.notesAndBuffersPool.start,
gAudioContext.notesAndBuffersPool.size);
GfxPrint_SetPos(printer, 3, 6);
GfxPrint_Printf(
printer, "AT-SEQ %02X-%02X (%05X-%05X / %05X)", (u8)gAudioContext.seqCache.temporary.entries[0].id,
(u8)gAudioContext.seqCache.temporary.entries[1].id, gAudioContext.seqCache.temporary.entries[0].size,
gAudioContext.seqCache.temporary.entries[1].size, gAudioContext.seqCache.temporary.pool.size);
GfxPrint_SetPos(printer, 3, 7);
GfxPrint_Printf(
printer, "AT-BNK %02X-%02X (%05X-%05X / %05X)", (u8)gAudioContext.fontCache.temporary.entries[0].id,
(u8)gAudioContext.fontCache.temporary.entries[1].id, gAudioContext.fontCache.temporary.entries[0].size,
gAudioContext.fontCache.temporary.entries[1].size, gAudioContext.fontCache.temporary.pool.size);
GfxPrint_SetPos(printer, 3, 8);
GfxPrint_Printf(printer, "ST-SEQ %02Xseqs (%05X / %06X)", gAudioContext.seqCache.persistent.numEntries,
gAudioContext.seqCache.persistent.pool.cur - gAudioContext.seqCache.persistent.pool.start,
gAudioContext.seqCache.persistent.pool.size);
for (k = 0; (u32)k < gAudioContext.seqCache.persistent.numEntries; k++) {
GfxPrint_SetPos(printer, 3 + 3 * k, 9);
GfxPrint_Printf(printer, "%02x", gAudioContext.seqCache.persistent.entries[k].id);
}
GfxPrint_SetPos(printer, 3, 10);
GfxPrint_Printf(printer, "ST-BNK %02Xbanks (%05X / %06X)", gAudioContext.fontCache.persistent.numEntries,
gAudioContext.fontCache.persistent.pool.cur - gAudioContext.fontCache.persistent.pool.start,
gAudioContext.fontCache.persistent.pool.size);
for (k = 0; (u32)k < gAudioContext.fontCache.persistent.numEntries; k++) {
GfxPrint_SetPos(printer, 3 + 3 * k, 11);
GfxPrint_Printf(printer, "%02x", gAudioContext.fontCache.persistent.entries[k].id);
}
GfxPrint_SetPos(printer, 3, 12);
GfxPrint_Printf(printer, "E-MEM %05X / %05X",
gAudioContext.permanentPool.cur - gAudioContext.permanentPool.start,
gAudioContext.permanentPool.size);
break;
case PAGE_BLOCK_CHANGE_BGM:
SETCOL(255, 255, 255);
GfxPrint_SetPos(printer, 3, 4);
GfxPrint_Printf(printer, "BGM No. %02X", sAudioBlkChgBgmWork[0]);
GfxPrint_SetPos(printer, 3, 5);
GfxPrint_Printf(printer, "SCENE SET %02X %s", sAudioBlkChgBgmWork[1],
sAudioSceneNames[sAudioBlkChgBgmWork[1]]);
SETCOL(0x64, 255, 0x64);
GfxPrint_SetPos(printer, 2, 4 + sAudioBlkChgBgmSel);
GfxPrint_Printf(printer, "*");
SETCOL(255, 255, 255);
GfxPrint_SetPos(printer, 3, 7);
GfxPrint_Printf(printer, "NEXT SCENE %02X %s",
(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[2],
sAudioSceneNames[(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[2]]);
GfxPrint_SetPos(printer, 3, 8);
GfxPrint_Printf(printer, "NOW SCENE %02X %s",
(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[4],
sAudioSceneNames[(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[4]]);
GfxPrint_SetPos(printer, 3, 9);
GfxPrint_Printf(printer, "NOW BLOCK %02X",
(gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[5] + 1) & 0xFF);
GfxPrint_SetPos(printer, 3, 11);
GfxPrint_Printf(printer, "PORT");
GfxPrint_SetPos(printer, 3, 12);
GfxPrint_Printf(printer, "%02X %02X %02X %02X",
(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[0],
(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[1],
(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[2],
(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[3]);
GfxPrint_SetPos(printer, 3, 13);
GfxPrint_Printf(printer, "%02X %02X %02X %02X",
(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[4],
(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[5],
(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[6],
(u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[7]);
break;
case PAGE_OCARINA_TEST:
SETCOL(255, 255, 255);
GfxPrint_SetPos(printer, 3, 4);
GfxPrint_Printf(printer, "SEQ INFO : %2d %02x %d", sPlaybackStaff.buttonIndex, sPlaybackStaff.state,
sPlaybackStaff.pos);
GfxPrint_SetPos(printer, 3, 5);
GfxPrint_Printf(printer, "PLAY INFO : %2d %02x %d", sPlayingStaff.buttonIndex, sPlayingStaff.state,
sPlayingStaff.pos);
GfxPrint_SetPos(printer, 3, 6);
GfxPrint_Printf(printer, "8note REC POINTER : %08x", gScarecrowSpawnSongPtr);
ctr = 0;
for (j = 0; j < 4; j++) {
for (i = 0; i < 8; i++) {
GfxPrint_SetPos(printer, 3 + 3 * i, 7 + j);
GfxPrint_Printf(printer, "%02x", gScarecrowSpawnSongPtr[ctr++]);
}
}
GfxPrint_SetPos(printer, 3, 24);
GfxPrint_Printf(printer, "OCA:%02x SEQ:%04x PLAY:%02x REC:%02x", sOcarinaInstrumentId, sOcarinaFlags,
sPlaybackState, sRecordingState);
break;
case PAGE_SFX_PARAMETER_CHANGE:
GfxPrint_SetPos(printer, 2, 4 + sAudioSfxParamChgSel);
SETCOL(127, 255, 127);
GfxPrint_Printf(printer, "*");
SETCOL(255, 255, 255);
GfxPrint_SetPos(printer, 3, 4);
GfxPrint_Printf(printer, "SE HD : %02x %s", sAudioSfxParamChgWork[0],
sSoundBankNames[sAudioSfxParamChgWork[0]]);
GfxPrint_SetPos(printer, 3, 5);
GfxPrint_Printf(printer, "SE No. : %02x", sAudioSfxParamChgWork[1]);
GfxPrint_SetPos(printer, 20, 6);
GfxPrint_Printf(printer, " : %04x",
gSoundParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].params);
GfxPrint_SetPos(printer, 3, 6);
GfxPrint_Printf(
printer, "SE SW %s",
AudioDebug_ToStringBinary(gSoundParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].params, 16));
SETCOL(127, 255, 127);
digitStr[0] = (char)('0' + ((gSoundParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].params >>
(15 - sAudioSfxParamChgBitSel)) &
1));
GfxPrint_SetPos(printer, 12 + sAudioSfxParamChgBitSel, 6);
GfxPrint_Printf(printer, "%s", digitStr);
SETCOL(255, 255, 255);
GfxPrint_SetPos(printer, 3, 7);
GfxPrint_Printf(printer, "SE PR : %02x",
gSoundParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].importance);
break;
case PAGE_FREE_AREA:
GfxPrint_SetPos(printer, 3, 4);
SETCOL(255, 255, 255);
GfxPrint_Printf(printer, "env_fx %d code_fx %d SPEC %d", sAudioEnvReverb, sAudioCodeReverb, gAudioSpecId);
if (sAudioUpdateTaskStart == sAudioUpdateTaskEnd) {
sAudioUpdateDuration = OS_CYCLES_TO_NSEC(sAudioUpdateEndTime - sAudioUpdateStartTime) / (1e9f / 20);
if (sAudioUpdateDurationMax < sAudioUpdateDuration) {
sAudioUpdateDurationMax = sAudioUpdateDuration;
}
}
GfxPrint_SetPos(printer, 3, 6);
GfxPrint_Printf(printer, "SOUND GAME FRAME NOW %f", sAudioUpdateDuration);
GfxPrint_SetPos(printer, 3, 7);
GfxPrint_Printf(printer, "SOUND GAME FRAME MAX %f", sAudioUpdateDurationMax);
GfxPrint_SetPos(printer, 3, 9);
GfxPrint_Printf(printer, "SWITCH BGM MODE %d %d %d (FLAG %d)", sPrevSeqMode, sNumFramesStill,
sNumFramesMoving, sSeqModeInput);
GfxPrint_SetPos(printer, 3, 10);
GfxPrint_Printf(printer, "ENEMY DIST %f VOL %3d", sAudioEnemyDist, sAudioEnemyVol);
GfxPrint_SetPos(printer, 3, 11);
GfxPrint_Printf(printer, "GANON DIST VOL %3d", sGanonsTowerVol);
GfxPrint_SetPos(printer, 3, 12);
GfxPrint_Printf(printer, "DEMO FLAG %d", sAudioCutsceneFlag);
GfxPrint_SetPos(printer, 3, 12);
if (sAudioHasMalonBgm == true) {
GfxPrint_Printf(printer, "MARON BGM DIST %f", sAudioMalonBgmDist);
sAudioHasMalonBgm = false;
}
GfxPrint_SetPos(printer, 3, 23);
if (sAudioNatureFailed != false) {
GfxPrint_Printf(printer, "NATURE FAILED %01x", sAudioNatureFailed);
}
GfxPrint_SetPos(printer, 3, 24);
if (sSariaBgmPtr != 0) {
GfxPrint_Printf(printer, "SARIA BGM PTR %08x", sSariaBgmPtr);
}
GfxPrint_SetPos(printer, 3, 25);
GfxPrint_Printf(printer, "POLI %d(%d)", sPeakNumNotes, numEnabledNotes);
for (i = 0; i < 11; i++) {
GfxPrint_SetPos(printer, 3 + 3 * i, 26);
GfxPrint_Printf(printer, "%d", sAudioSpecPeakNumNotes[i]);
}
break;
}
#undef SETCOL_COMMON
#undef SETCOL
#undef SETCOL_SCROLLPRINT
}
void AudioDebug_ProcessInput_SndCont(void) {
u16 step = 1;
if (CHECK_BTN_ANY(sDebugPadHold, BTN_CDOWN)) {
if (sAudioSndContWorkLims[sAudioSndContSel] >= 16) {
step = 16;
}
} else if (CHECK_BTN_ANY(sDebugPadHold, BTN_CLEFT)) {
if (sAudioSndContWorkLims[sAudioSndContSel] >= 16) {
step = 8;
}
} else if (CHECK_BTN_ANY(sDebugPadHold, BTN_CUP)) {
sAudioSndContWork[sAudioSndContSel] = 0;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) {
if (sAudioSndContSel > 0) {
sAudioSndContSel--;
} else {
sAudioSndContSel = 10;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) {
if (sAudioSndContSel < 10) {
sAudioSndContSel++;
} else {
sAudioSndContSel = 0;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) {
if (sAudioSndContWork[sAudioSndContSel] >= step) {
if (1) {
sAudioSndContWork[sAudioSndContSel] -= step;
}
} else {
sAudioSndContWork[sAudioSndContSel] += sAudioSndContWorkLims[sAudioSndContSel] - step;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) {
if (sAudioSndContWork[sAudioSndContSel] + step < sAudioSndContWorkLims[sAudioSndContSel]) {
sAudioSndContWork[sAudioSndContSel] += step;
} else {
sAudioSndContWork[sAudioSndContSel] += step - sAudioSndContWorkLims[sAudioSndContSel];
}
}
if (sAudioSndContSel == 8) {
if (sAudioSndContWork[sAudioSndContSel] != 0) {
Audio_SetExtraFilter(0x20);
} else {
Audio_SetExtraFilter(0);
}
}
if (sAudioSndContSel == 9) {
if (sAudioSndContWork[sAudioSndContSel] != 0) {
Audio_SetBaseFilter(0x20);
} else {
Audio_SetBaseFilter(0);
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) {
switch (sAudioSndContSel) {
case 0:
case 1:
Audio_StartSeq(sAudioSndContSel, 0, sAudioSndContWork[sAudioSndContSel]);
break;
case 2:
case 3:
Audio_PlaySoundGeneral(((sAudioSndContWork[2] << 12) & 0xFFFF) + sAudioSndContWork[3] + SFX_FLAG,
&gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb);
break;
case 4:
func_800F6700(sAudioSndContWork[sAudioSndContSel]);
break;
case 5:
Audio_SeqCmdE01(SEQ_PLAYER_BGM_MAIN, sAudioSndContWork[sAudioSndContSel]);
break;
case 6:
Audio_SeqCmdF(SEQ_PLAYER_BGM_MAIN, sAudioSndContWork[sAudioSndContSel]);
sAudioSubTrackInfoSpec = sAudioSndContWork[6];
if (sAudioSubTrackInfoPlayerSel > gAudioSpecs[sAudioSubTrackInfoSpec].numSequencePlayers - 1) {
sAudioSubTrackInfoPlayerSel = gAudioSpecs[sAudioSubTrackInfoSpec].numSequencePlayers - 1;
}
break;
case 7:
Audio_PlayNatureAmbienceSequence(sAudioSndContWork[sAudioSndContSel]);
break;
case 8:
case 9:
break;
case 10:
Audio_SetSoundBanksMute(sAudioSndContWork[sAudioSndContSel] * 0x7F);
break;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) {
switch (sAudioSndContSel) {
case 0:
case 1:
Audio_SeqCmd1(sAudioSndContSel, 0);
break;
case 7:
Audio_SeqCmd1(SEQ_PLAYER_BGM_MAIN, 0);
break;
case 2:
case 3:
Audio_StopSfxByBank(sAudioSndContWork[2]);
break;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CDOWN)) {
if (sAudioSndContSel == 0) {
if (1) {}
func_800F595C(sAudioSndContWork[sAudioSndContSel]);
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CRIGHT)) {
if (sAudioSndContSel == 0) {
if (1) {}
func_800F5ACC(sAudioSndContWork[sAudioSndContSel]);
}
}
}
void AudioDebug_ProcessInput_IntInfo(void) {
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CUP)) {
sAudioIntInfoY--;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CDOWN)) {
sAudioIntInfoY++;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CLEFT)) {
sAudioIntInfoX--;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CRIGHT)) {
sAudioIntInfoX++;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) {
sAudioIntInfoX = 0;
sAudioIntInfoY = 0;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP) && sAudioIntInfoSel > 0) {
sAudioIntInfoSel--;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN) && sAudioIntInfoSel < 6) {
sAudioIntInfoSel++;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT) && sAudioIntInfoBankPage[sAudioIntInfoSel] > 0) {
sAudioIntInfoBankPage[sAudioIntInfoSel]--;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT) && sAudioIntInfoBankPage[sAudioIntInfoSel] < 4) {
sAudioIntInfoBankPage[sAudioIntInfoSel]++;
}
}
void AudioDebug_ProcessInput_ScrPrt(void) {
if (sAudioScrPrtWork[0] != 0) {
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CUP)) {
sAudioScrPrtY--;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CDOWN)) {
sAudioScrPrtY++;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CLEFT)) {
sAudioScrPrtX--;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CRIGHT)) {
sAudioScrPrtX++;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) {
sAudioScrPrtX = 26;
sAudioScrPrtY = 1;
sAudioScrPrtWork[2] = 6;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) {
sAudioScrPrtInd = 0;
sAudioScrPrtOverflow = 0;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) {
if (sAudioScrPrtSel > 0) {
sAudioScrPrtSel--;
} else {
sAudioScrPrtSel = 10;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) {
if (sAudioScrPrtSel < 10) {
sAudioScrPrtSel++;
} else {
sAudioScrPrtSel = 0;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) {
if (sAudioScrPrtWork[sAudioScrPrtSel] > 0) {
sAudioScrPrtWork[sAudioScrPrtSel]--;
} else {
sAudioScrPrtWork[sAudioScrPrtSel] = sAudioScrPrtWorkLims[sAudioScrPrtSel] - 1;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) {
if (sAudioScrPrtWork[sAudioScrPrtSel] < sAudioScrPrtWorkLims[sAudioScrPrtSel] - 1) {
sAudioScrPrtWork[sAudioScrPrtSel]++;
} else {
sAudioScrPrtWork[sAudioScrPrtSel] = 0;
}
}
D_801333F0 = sAudioScrPrtWork[3] + (sAudioScrPrtWork[4] * 2) + (sAudioScrPrtWork[5] * 4) +
(sAudioScrPrtWork[6] * 8) + (sAudioScrPrtWork[7] * 0x10) + (sAudioScrPrtWork[8] * 0x20);
}
void AudioDebug_ProcessInput_SfxSwap(void) {
s16 step;
u16 val;
u8 prev;
if (!sAudioSfxSwapIsEditing) {
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) {
if (sAudioSfxSwapSel > 0) {
sAudioSfxSwapSel--;
} else {
sAudioSfxSwapSel = 9;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) {
if (sAudioSfxSwapSel < 9) {
sAudioSfxSwapSel++;
} else {
sAudioSfxSwapSel = 0;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) {
sAudioSfxSwapIsEditing = true;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) {
gAudioSfxSwapSource[sAudioSfxSwapSel] = 0;
gAudioSfxSwapTarget[sAudioSfxSwapSel] = 0;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_START)) {
if (sAudioSfxSwapSel != 0) {
prev = sAudioSfxSwapSel - 1;
} else {
prev = 9;
}
gAudioSfxSwapSource[sAudioSfxSwapSel] = gAudioSfxSwapSource[prev];
gAudioSfxSwapTarget[sAudioSfxSwapSel] = gAudioSfxSwapTarget[prev];
}
} else {
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) {
if (sAudioSfxSwapNibbleSel > 0) {
sAudioSfxSwapNibbleSel--;
} else {
sAudioSfxSwapNibbleSel = 7;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) {
if (sAudioSfxSwapNibbleSel < 7) {
sAudioSfxSwapNibbleSel++;
} else {
sAudioSfxSwapNibbleSel = 0;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP) || CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) {
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) {
step = CHECK_BTN_ANY(sDebugPadHold, BTN_CUP) ? 8 : 1;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) {
step = CHECK_BTN_ANY(sDebugPadHold, BTN_CUP) ? -8 : -1;
}
if (sAudioSfxSwapNibbleSel < 4) {
val = gAudioSfxSwapSource[sAudioSfxSwapSel] >> ((3 - sAudioSfxSwapNibbleSel) * 4);
val = (val + step) & 0xF;
gAudioSfxSwapSource[sAudioSfxSwapSel] =
(gAudioSfxSwapSource[sAudioSfxSwapSel] & ((0xF << ((3 - sAudioSfxSwapNibbleSel) * 4)) ^ 0xFFFF)) +
(val << ((3 - sAudioSfxSwapNibbleSel) * 4));
} else {
val = gAudioSfxSwapTarget[sAudioSfxSwapSel] >> ((7 - sAudioSfxSwapNibbleSel) * 4);
val = (val + step) & 0xF;
gAudioSfxSwapTarget[sAudioSfxSwapSel] =
(gAudioSfxSwapTarget[sAudioSfxSwapSel] & ((0xF << ((7 - sAudioSfxSwapNibbleSel) * 4)) ^ 0xFFFF)) +
(val << ((7 - sAudioSfxSwapNibbleSel) * 4));
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) {
sAudioSfxSwapIsEditing = false;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) {
if (sAudioSfxSwapNibbleSel < 4) {
gAudioSfxSwapSource[sAudioSfxSwapSel] = 0;
} else {
gAudioSfxSwapTarget[sAudioSfxSwapSel] = 0;
}
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CLEFT)) {
gAudioSfxSwapOff ^= 1;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CDOWN)) {
gAudioSfxSwapMode[sAudioSfxSwapSel] ^= 1;
}
}
void AudioDebug_ProcessInput_SubTrackInfo(void) {
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) {
if (sAudioSubTrackInfoPlayerSel != 0) {
sAudioSubTrackInfoPlayerSel--;
} else {
sAudioSubTrackInfoPlayerSel = gAudioSpecs[sAudioSubTrackInfoSpec].numSequencePlayers - 1;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) {
if (sAudioSubTrackInfoPlayerSel < gAudioSpecs[sAudioSubTrackInfoSpec].numSequencePlayers - 1) {
sAudioSubTrackInfoPlayerSel++;
} else {
sAudioSubTrackInfoPlayerSel = SEQ_PLAYER_BGM_MAIN;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) {
sAudioSubTrackInfoChannelSel = (sAudioSubTrackInfoChannelSel - 1) & 0xF;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) {
sAudioSubTrackInfoChannelSel = (sAudioSubTrackInfoChannelSel + 1) & 0xF;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_START)) {
sSeqPlayerPeakNumLayers[sAudioSubTrackInfoPlayerSel] = SEQ_PLAYER_BGM_MAIN;
}
}
void AudioDebug_ProcessInput_HeapInfo(void) {
}
void AudioDebug_ProcessInput_BlkChgBgm(void) {
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) {
if (sAudioBlkChgBgmSel > 0) {
sAudioBlkChgBgmSel--;
} else {
sAudioBlkChgBgmSel = 1;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) {
if (sAudioBlkChgBgmSel <= 0) {
sAudioBlkChgBgmSel++;
} else {
sAudioBlkChgBgmSel = 0;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) {
sAudioBlkChgBgmWork[sAudioBlkChgBgmSel]--;
if (sAudioBlkChgBgmSel == 1) {
Audio_SetSequenceMode(sAudioBlkChgBgmWork[1]);
; // might be a fake match?
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) {
sAudioBlkChgBgmWork[sAudioBlkChgBgmSel]++;
if (sAudioBlkChgBgmSel == 1) {
Audio_SetSequenceMode(sAudioBlkChgBgmWork[1]);
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) {
Audio_QueueCmdS8(MK_CMD(0x46, SEQ_PLAYER_BGM_MAIN, 0x00, 0x00), sAudioBlkChgBgmWork[1]);
Audio_QueueSeqCmd(sAudioBlkChgBgmWork[0] | 0x10000);
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) {
Audio_QueueSeqCmd(0x100100FF);
}
}
void AudioDebug_ProcessInput_OcaTest(void) {
}
void AudioDebug_ProcessInput_SfxParamChg(void) {
s32 step;
u16 sfx;
if (CHECK_BTN_ANY(sDebugPadHold, BTN_CLEFT)) {
step = 8;
} else {
step = 1;
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) {
if (sAudioSfxParamChgSel > 0) {
sAudioSfxParamChgSel--;
} else {
sAudioSfxParamChgSel = 3;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) {
if (sAudioSfxParamChgSel < 3) {
sAudioSfxParamChgSel++;
} else {
sAudioSfxParamChgSel = 0;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) {
if (sAudioSfxParamChgSel < 2) {
if (sAudioSfxParamChgSel == 0) {
if (sAudioSfxParamChgWork[sAudioSfxParamChgSel] > 0) {
sAudioSfxParamChgWork[sAudioSfxParamChgSel]--;
} else {
sAudioSfxParamChgWork[sAudioSfxParamChgSel] = sAudioSndContWorkLims[2] - 1;
}
} else {
sAudioSfxParamChgWork[sAudioSfxParamChgSel] -= step;
sAudioSfxParamChgWork[sAudioSfxParamChgSel] &= 0x1FF;
}
} else if (sAudioSfxParamChgSel == 3) {
gSoundParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].importance -= step;
} else {
sAudioSfxParamChgBitSel = (sAudioSfxParamChgBitSel - 1) & 0xF;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) {
if (sAudioSfxParamChgSel < 2) {
if (sAudioSfxParamChgSel == 0) {
if (sAudioSfxParamChgWork[sAudioSfxParamChgSel] < (sAudioSndContWorkLims[2] - 1)) {
sAudioSfxParamChgWork[sAudioSfxParamChgSel]++;
} else {
sAudioSfxParamChgWork[sAudioSfxParamChgSel] = 0;
}
} else {
sAudioSfxParamChgWork[sAudioSfxParamChgSel] += step;
sAudioSfxParamChgWork[sAudioSfxParamChgSel] &= 0x1FF;
}
} else if (sAudioSfxParamChgSel == 3) {
gSoundParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].importance += step;
} else {
sAudioSfxParamChgBitSel = (sAudioSfxParamChgBitSel + 1) & 0xF;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) {
sfx = (u16)(sAudioSfxParamChgWork[0] << 12) + sAudioSfxParamChgWork[1] + SFX_FLAG;
Audio_PlaySoundGeneral(sfx, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb);
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) {
Audio_StopSfxByBank(sAudioSfxParamChgWork[0]);
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CDOWN)) {
if (sAudioSfxParamChgSel == 2) {
gSoundParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].params ^=
(1 << (0xF - sAudioSfxParamChgBitSel));
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_CUP)) {
if (sAudioSfxParamChgSel < 2) {
sAudioSfxParamChgWork[sAudioSfxParamChgSel] = 0;
}
}
}
void AudioDebug_ScrPrt(const s8* str, u16 num) {
u8 i = 0;
sAudioScrPrtBuf[sAudioScrPrtInd].num = num;
while (str[i] != 0) {
sAudioScrPrtBuf[sAudioScrPrtInd].str[i] = str[i];
i++;
}
while (i < 5) {
sAudioScrPrtBuf[sAudioScrPrtInd].str[i] = 0;
i++;
}
if (sAudioScrPrtInd < 25 - 1) {
sAudioScrPrtInd++;
} else {
sAudioScrPrtInd = 0;
sAudioScrPrtOverflow = 1;
}
}
void AudioDebug_ProcessInput(void) {
if (!sAudioDebugEverOpened) {
return;
}
if (sAudioSfxMuted) {
Audio_SetSoundBanksMute(0x6F);
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_L)) {
if (sAudioDebugPage < PAGE_MAX - 1) {
sAudioDebugPage++;
} else {
sAudioDebugPage = 0;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_R)) {
if (sAudioDebugPage > 0) {
sAudioDebugPage--;
} else {
sAudioDebugPage = PAGE_MAX - 1;
}
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_Z)) {
sAudioDebugTextColor++;
sAudioDebugTextColor &= 7;
}
switch (sAudioDebugPage) {
case PAGE_NON:
if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) {
sAudioSndContWork[5] ^= 1;
Audio_SeqCmdE01(SEQ_PLAYER_BGM_MAIN, sAudioSndContWork[5]);
if (func_800FA0B4(SEQ_PLAYER_BGM_MAIN) != NA_BGM_NATURE_AMBIENCE) {
Audio_SeqCmd1(SEQ_PLAYER_BGM_MAIN, 0);
}
Audio_SeqCmd1(SEQ_PLAYER_FANFARE, 0);
Audio_SeqCmd1(SEQ_PLAYER_BGM_SUB, 0);
}
if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) {
sAudioSfxMuted ^= 1;
if (!sAudioSfxMuted) {
Audio_SetSoundBanksMute(0);
}
}
break;
case PAGE_SOUND_CONTROL:
AudioDebug_ProcessInput_SndCont();
break;
case PAGE_INTERFACE_INFO:
AudioDebug_ProcessInput_IntInfo();
break;
case PAGE_SCROLL_PRINT:
AudioDebug_ProcessInput_ScrPrt();
break;
case PAGE_SFX_SWAP:
AudioDebug_ProcessInput_SfxSwap();
break;
case PAGE_SUB_TRACK_INFO:
AudioDebug_ProcessInput_SubTrackInfo();
break;
case PAGE_HEAP_INFO:
AudioDebug_ProcessInput_HeapInfo();
break;
case PAGE_BLOCK_CHANGE_BGM:
AudioDebug_ProcessInput_BlkChgBgm();
break;
case PAGE_OCARINA_TEST:
AudioDebug_ProcessInput_OcaTest();
break;
case PAGE_SFX_PARAMETER_CHANGE:
AudioDebug_ProcessInput_SfxParamChg();
break;
case PAGE_FREE_AREA:
default:
break;
}
D_8013340C = sAudioScrPrtWork[10];
}
void Audio_UpdateRiverSoundVolumes(void);
void func_800F5CF8(void);
/**
* This is Audio_Update for the graph thread
*/
void func_800F3054(void) {
if (func_800FAD34() == 0) {
sAudioUpdateTaskStart = gAudioContext.totalTaskCount;
sAudioUpdateStartTime = osGetTime();
AudioOcarina_Update();
Audio_StepFreqLerp(&sRiverFreqScaleLerp);
Audio_StepFreqLerp(&sWaterfallFreqScaleLerp);
Audio_UpdateRiverSoundVolumes();
func_800F56A8();
func_800F5CF8();
if (gAudioSpecId == 7) {
Audio_ClearSariaBgm();
}
Audio_ProcessSoundRequests();
Audio_ProcessSeqCmds();
func_800F8F88();
func_800FA3DC();
AudioDebug_SetInput();
AudioDebug_ProcessInput();
Audio_ScheduleProcessCmds();
sAudioUpdateTaskEnd = gAudioContext.totalTaskCount;
sAudioUpdateEndTime = osGetTime();
}
}
void func_800F3138(UNK_TYPE arg0) {
}
void func_800F3140(UNK_TYPE arg0, UNK_TYPE arg1) {
}
void func_800F314C(s8 arg0) {
Audio_QueueCmdS32(0x82 << 24 | SEQ_PLAYER_BGM_MAIN << 16 | (((u8)arg0 & 0xFF) << 8), 1);
}
f32 Audio_ComputeSoundVolume(u8 bankId, u8 entryIdx) {
SoundBankEntry* bankEntry = &gSoundBanks[bankId][entryIdx];
f32 minDist;
f32 baseDist;
f32 ret;
if (bankEntry->sfxParams & 0x2000) {
return 1.0f;
}
if (bankEntry->dist > 10000.0f) {
ret = 0.0f;
} else {
switch (bankEntry->sfxParams & 3) {
case 1:
baseDist = 10000.0f / 15.0f;
break;
case 2:
baseDist = 10000.0f / 10.5f;
break;
case 3:
baseDist = 10000.0f / 2.6f;
break;
default:
baseDist = 10000.0f / 20.0f;
break;
}
minDist = baseDist / 5.0f;
// Volume grows as inverse square of distance. Linearly approximate
// the inverse part, then square.
if (bankEntry->dist < minDist) {
ret = 1.0f;
} else if (bankEntry->dist < baseDist) {
ret = ((((baseDist - minDist) - (bankEntry->dist - minDist)) / (baseDist - minDist)) * 0.19f) + 0.81f;
} else {
ret = (1.0f - ((bankEntry->dist - baseDist) / (10000.0f - baseDist))) * 0.81f;
}
ret = SQ(ret);
}
return ret;
}
s8 Audio_ComputeSoundReverb(u8 bankId, u8 entryIdx, u8 channelIdx) {
s8 distAdd = 0;
s32 scriptAdd = 0;
SoundBankEntry* entry = &gSoundBanks[bankId][entryIdx];
s32 reverb;
if (!(entry->sfxParams & 0x1000)) {
if (entry->dist < 2500.0f) {
distAdd = *entry->posZ > 0.0f ? (entry->dist / 2500.0f) * 70.0f : (entry->dist / 2500.0f) * 91.0f;
} else {
distAdd = 70;
}
}
if (IS_SEQUENCE_CHANNEL_VALID(gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[channelIdx])) {
scriptAdd = gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[channelIdx]->soundScriptIO[1];
if (gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[channelIdx]->soundScriptIO[1] < 0) {
scriptAdd = 0;
}
}
reverb = *entry->reverbAdd + distAdd + scriptAdd;
if ((bankId != BANK_OCARINA) || !((entry->sfxId & 0x1FF) < 2)) {
reverb += sAudioEnvReverb + sAudioCodeReverb + sSpecReverb;
}
if (reverb > 0x7F) {
reverb = 0x7F;
}
return reverb;
}
s8 Audio_ComputeSoundPanSigned(f32 x, f32 z, u8 token) {
f32 absX;
f32 absZ;
f32 pan;
if (x < 0) {
absX = -x;
} else {
absX = x;
}
if (z < 0) {
absZ = -z;
} else {
absZ = z;
}
if (absX > 8000.0f) {
absX = 8000.0f;
}
if (absZ > 8000.0f) {
absZ = 8000.0f;
}
if ((x == 0.0f) && (z == 0.0f)) {
pan = 0.5f;
} else if (absZ <= absX) {
pan = (16000.0f - absX) / (3.3f * (16000.0f - absZ));
if (x >= 0.0f) {
pan = 1.0f - pan;
}
} else {
pan = (x / (5.0769234f * absZ)) + 0.5f; // about 66 / 13
}
if (absZ < 50.0f) {
if (absX < 50.0f) {
pan = ((pan - 0.5f) * SQ(absX / 50.0f)) + 0.5f;
}
}
return (s8)((pan * 127.0f) + 0.5f);
}
f32 Audio_ComputeSoundFreqScale(u8 bankId, u8 entryIdx) {
s32 phi_v0 = 0;
SoundBankEntry* entry = &gSoundBanks[bankId][entryIdx];
f32 unk1C;
f32 freq = 1.0f;
if (entry->sfxParams & 0x4000) {
freq = 1.0f - ((gAudioContext.audioRandom & 0xF) / 192.0f);
}
switch (bankId) {
case BANK_PLAYER:
case BANK_ITEM:
case BANK_VOICE:
if (sAudioBaseFilter2 != 0) {
phi_v0 = 1;
}
break;
case BANK_ENV:
case BANK_ENEMY:
if (sAudioExtraFilter2 != 0) {
phi_v0 = 1;
}
break;
case BANK_SYSTEM:
case BANK_OCARINA:
break;
}
if (phi_v0 == 1) {
if (!(entry->sfxParams & 0x800)) {
freq *= (1.0293 - ((gAudioContext.audioRandom & 0xF) / 144.0f));
}
}
unk1C = entry->dist;
if (!(entry->sfxParams & 0x2000)) {
if (!(entry->sfxParams & 0x8000)) {
if (unk1C >= 10000.0f) {
freq += 0.2f;
} else {
freq += (0.2f * (unk1C / 10000.0f));
}
}
}
if (entry->sfxParams & 0xC0) {
freq += (entry->unk_2F / 192.0f);
}
return freq;
}
u8 func_800F37B8(f32 behindScreenZ, SoundBankEntry* arg1, s8 arg2) {
s8 phi_v0;
u8 phi_v1;
f32 phi_f0;
f32 phi_f12;
if (*arg1->posZ < behindScreenZ) {
phi_v0 = arg2 < 65 ? arg2 : 0x7F - arg2;
if (phi_v0 < 30) {
phi_v1 = 0;
} else {
phi_v1 = (((phi_v0 & 0xFFFF) * 10) - 300) / 34;
if (phi_v1 != 0) {
phi_v1 = 0x10 - phi_v1;
}
}
} else {
phi_v1 = 0;
}
if (phi_v1 == 0) {
if (arg1->sfxParams & 0x200) {
phi_v1 = 0xF;
}
}
switch (arg1->sfxParams & 3) {
case 1:
phi_f0 = 12.0f;
break;
case 2:
phi_f0 = 9.0f;
break;
case 3:
phi_f0 = 6.0f;
break;
default:
phi_f0 = 15.0f;
break;
}
phi_f12 = CLAMP_MAX(arg1->dist, 10000.0f / 5.2f);
return (phi_v1 * 0x10) + (u8)((phi_f0 * phi_f12) / (10000.0f / 5.2f));
}
s8 func_800F3990(f32 arg0, u16 sfxParams) {
s8 ret = 0;
if (arg0 >= 0.0f) {
if (arg0 > 625.0f) {
ret = 127;
} else {
ret = (arg0 / 625.0f) * 126.0f;
}
}
return ret | 1;
}
void Audio_SetSoundProperties(u8 bankId, u8 entryIdx, u8 channelIdx) {
f32 vol = 1.0f;
s8 volS8;
s8 reverb = 0;
f32 freqScale = 1.0f;
s8 panSigned = 0x40;
u8 stereoBits = 0;
u8 filter = 0;
s8 sp38 = 0;
f32 behindScreenZ;
u8 baseFilter = 0;
SoundBankEntry* entry = &gSoundBanks[bankId][entryIdx];
switch (bankId) {
case BANK_PLAYER:
case BANK_ITEM:
case BANK_ENV:
case BANK_ENEMY:
case BANK_VOICE:
if (D_80130604 == 2) {
sp38 = func_800F3990(*entry->posY, entry->sfxParams);
}
// fallthrough
case BANK_OCARINA:
entry->dist = sqrtf(entry->dist);
vol = Audio_ComputeSoundVolume(bankId, entryIdx) * *entry->vol;
reverb = Audio_ComputeSoundReverb(bankId, entryIdx, channelIdx);
panSigned = Audio_ComputeSoundPanSigned(*entry->posX, *entry->posZ, entry->token);
freqScale = Audio_ComputeSoundFreqScale(bankId, entryIdx) * *entry->freqScale;
if (D_80130604 == 2) {
behindScreenZ = sBehindScreenZ[(entry->sfxParams & 0x400) >> 10];
if (!(entry->sfxParams & 0x800)) {
if (*entry->posZ < behindScreenZ) {
stereoBits = 0x10;
}
if ((sSfxChannelState[channelIdx].stereoBits ^ stereoBits) & 0x10) {
if (panSigned < 0x40) {
stereoBits = sSfxChannelState[channelIdx].stereoBits ^ 0x14;
} else {
stereoBits = sSfxChannelState[channelIdx].stereoBits ^ 0x18;
}
} else {
stereoBits = sSfxChannelState[channelIdx].stereoBits;
}
}
}
if (sAudioBaseFilter != 0) {
if ((bankId == BANK_ITEM) || (bankId == BANK_PLAYER) || (bankId == BANK_VOICE)) {
baseFilter = sAudioBaseFilter;
}
}
if ((baseFilter | sAudioExtraFilter) != 0) {
filter = (baseFilter | sAudioExtraFilter);
} else if (D_80130604 == 2 && (entry->sfxParams & 0x2000) == 0) {
filter = func_800F37B8(behindScreenZ, entry, panSigned);
}
break;
case BANK_SYSTEM:
break;
}
if (sSfxChannelState[channelIdx].vol != vol) {
volS8 = (u8)(vol * 127.0f);
sSfxChannelState[channelIdx].vol = vol;
} else {
volS8 = -1;
}
// CHAN_UPD_SCRIPT_IO (slot 2, sets volume)
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8) | 2, volS8);
if (reverb != sSfxChannelState[channelIdx].reverb) {
Audio_QueueCmdS8(0x5 << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), reverb);
sSfxChannelState[channelIdx].reverb = reverb;
}
if (freqScale != sSfxChannelState[channelIdx].freqScale) {
Audio_QueueCmdF32(0x4 << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), freqScale);
sSfxChannelState[channelIdx].freqScale = freqScale;
}
if (stereoBits != sSfxChannelState[channelIdx].stereoBits) {
Audio_QueueCmdS8(0xE << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), stereoBits | 0x10);
sSfxChannelState[channelIdx].stereoBits = stereoBits;
}
if (filter != sSfxChannelState[channelIdx].filter) {
// CHAN_UPD_SCRIPT_IO (slot 3, sets filter)
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8) | 3, filter);
sSfxChannelState[channelIdx].filter = filter;
}
if (sp38 != sSfxChannelState[channelIdx].unk_0C) {
// CHAN_UPD_UNK_0F
Audio_QueueCmdS8(0xC << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), 0x10);
// CHAN_UPD_UNK_20
Audio_QueueCmdU16(0xD << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), ((u16)(sp38) << 8) + 0xFF);
sSfxChannelState[channelIdx].unk_0C = sp38;
}
if (panSigned != sSfxChannelState[channelIdx].panSigned) {
Audio_QueueCmdS8(0x3 << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), panSigned);
sSfxChannelState[channelIdx].panSigned = panSigned;
}
}
void Audio_ResetSfxChannelState(void) {
u8 i;
SfxPlayerState* state;
for (i = 0; i < 16; i++) {
state = &sSfxChannelState[i];
state->vol = 1.0f;
state->freqScale = 1.0f;
state->reverb = 0;
state->panSigned = 0x40;
state->stereoBits = 0;
state->filter = 0xFF;
state->unk_0C = 0xFF;
}
sSfxChannelState[SFX_CHANNEL_OCARINA].unk_0C = 0;
sPrevSeqMode = 0;
sAudioCodeReverb = 0;
}
void func_800F3F3C(u8 arg0) {
if (gSoundBankMuted[0] != 1) {
Audio_StartSeq(SEQ_PLAYER_BGM_SUB, 0, NA_BGM_VARIOUS_SFX);
Audio_SeqCmd8(SEQ_PLAYER_BGM_SUB, 0, 0, arg0);
}
}
f32 func_800F3F84(f32 arg0) {
f32 ret = 1.0f;
if (arg0 > 6.0f) {
D_8016B7A8 = 1.0f;
D_8016B7B0 = 1.1f;
} else {
ret = arg0 / 6.0f;
D_8016B7A8 = (ret * 0.22500002f) + 0.775f;
D_8016B7B0 = (ret * 0.2f) + 0.9f;
}
return ret;
}
void func_800F4010(Vec3f* pos, u16 sfxId, f32 arg2) {
f32 sp24;
f32 phi_f0;
u8 phi_v0;
u16 sfxId2;
D_80131C8C = arg2;
sp24 = func_800F3F84(arg2);
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &gSfxDefaultReverb);
if ((sfxId & 0xF0) == 0xB0) {
phi_f0 = 0.3f;
phi_v0 = 1;
sp24 = 1.0f;
} else {
phi_f0 = 1.1f;
phi_v0 = gAudioContext.audioRandom % 2;
}
if ((phi_f0 < arg2) && (phi_v0 != 0)) {
if ((sfxId & 0x80) != 0) {
sfxId2 = NA_SE_PL_METALEFFECT_ADULT;
} else {
sfxId2 = NA_SE_PL_METALEFFECT_KID;
}
D_8016B7AC = (sp24 * 0.7) + 0.3;
Audio_PlaySoundGeneral(sfxId2, pos, 4, &D_8016B7B0, &D_8016B7AC, &gSfxDefaultReverb);
}
}
void func_800F4138(Vec3f* pos, u16 sfxId, f32 arg2) {
func_800F3F84(arg2);
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &gSfxDefaultReverb);
}
void func_800F4190(Vec3f* pos, u16 sfxId) {
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801305B0, &gSfxDefaultFreqAndVolScale, &D_801305B4);
}
void Audio_PlaySoundRandom(Vec3f* pos, u16 baseSfxId, u8 randLim) {
u8 offset = Audio_NextRandom() % randLim;
Audio_PlaySoundGeneral(baseSfxId + offset, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb);
}
void func_800F4254(Vec3f* pos, u8 level) {
level &= 3;
if (level != sPrevChargeLevel) {
D_801305F4 = D_801305E4[level];
switch (level) {
case 1:
Audio_PlaySoundGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb);
break;
case 2:
Audio_PlaySoundGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb);
break;
}
sPrevChargeLevel = level;
}
if (level != 0) {
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_CHARGE - SFX_FLAG, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb);
}
}
void func_800F436C(Vec3f* pos, u16 sfxId, f32 arg2) {
if (arg2 < 0.75f) {
D_8016B7D8 = ((arg2 / 0.75f) * 0.25f) + 0.5f;
} else {
D_8016B7D8 = arg2;
}
if (D_8016B7D8 > 0.5f) {
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7D8, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
}
}
void func_800F4414(Vec3f* pos, u16 sfxId, f32 arg2) {
D_801305B8--;
if (D_801305B8 == 0) {
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7D8, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
if (arg2 > 2.0f) {
arg2 = 2.0f;
}
D_801305B8 = (s8)((D_801305C0 - D_801305BC) * (1.0f - arg2)) + D_801305C0;
}
}
void func_800F44EC(s8 arg0, s8 arg1) {
D_801305B8 = 1;
D_801305BC = arg1;
D_801305C0 = arg0;
}
void func_800F4524(Vec3f* pos, u16 sfxId, s8 arg2) {
D_8016B7DC = arg2;
Audio_PlaySoundGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &D_8016B7DC);
}
void func_800F4578(Vec3f* pos, u16 sfxId, f32 arg2) {
D_8016B7E0 = arg2;
Audio_PlaySoundGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &D_8016B7E0, &gSfxDefaultReverb);
}
void func_800F45D0(f32 arg0) {
func_800F4414(&gSfxDefaultPos, NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG, arg0);
func_800F436C(&gSfxDefaultPos, 0, (0.15f * arg0) + 1.4f);
}
void Audio_PlaySoundRiver(Vec3f* pos, f32 freqScale) {
if (!Audio_IsSfxPlaying(NA_SE_EV_RIVER_STREAM - SFX_FLAG)) {
sRiverFreqScaleLerp.value = freqScale;
} else if (freqScale != sRiverFreqScaleLerp.value) {
sRiverFreqScaleLerp.target = freqScale;
sRiverFreqScaleLerp.remainingFrames = 40;
sRiverFreqScaleLerp.step = (sRiverFreqScaleLerp.target - sRiverFreqScaleLerp.value) / 40;
}
Audio_PlaySoundGeneral(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
}
void Audio_PlaySoundWaterfall(Vec3f* pos, f32 freqScale) {
if (!Audio_IsSfxPlaying(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG)) {
sWaterfallFreqScaleLerp.value = freqScale;
} else if (freqScale != sWaterfallFreqScaleLerp.value) {
sWaterfallFreqScaleLerp.target = freqScale;
sWaterfallFreqScaleLerp.remainingFrames = 40;
sWaterfallFreqScaleLerp.step = (sWaterfallFreqScaleLerp.target - sWaterfallFreqScaleLerp.value) / 40;
}
Audio_PlaySoundGeneral(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value,
&sWaterfallFreqScaleLerp.value, &gSfxDefaultReverb);
}
void Audio_StepFreqLerp(FreqLerp* lerp) {
if (lerp->remainingFrames != 0) {
lerp->remainingFrames--;
if (lerp->remainingFrames != 0) {
lerp->value += lerp->step;
} else {
lerp->value = lerp->target;
}
}
}
void func_800F47BC(void) {
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 1, 0, 10);
Audio_SetVolScale(SEQ_PLAYER_BGM_SUB, 1, 0, 10);
}
void func_800F47FC(void) {
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 1, 0x7F, 3);
Audio_SetVolScale(SEQ_PLAYER_BGM_SUB, 1, 0x7F, 3);
}
void func_800F483C(u8 targetVol, u8 volFadeTimer) {
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 0, targetVol, volFadeTimer);
}
/**
* Incrementally increase volume of NA_BGM_GANON_TOWER for each new room during the climb of Ganon's Tower
*/
void Audio_SetGanonsTowerBgmVolumeLevel(u8 ganonsTowerLevel) {
u8 channelIdx;
s8 pan = 0;
// Ganondorf's Lair
if (ganonsTowerLevel == 0) {
pan = 0x7F;
}
for (channelIdx = 0; channelIdx < 16; channelIdx++) {
// CHAN_UPD_PAN_UNSIGNED
Audio_QueueCmdS8(_SHIFTL(0x7, 24, 8) | _SHIFTL(SEQ_PLAYER_BGM_MAIN, 16, 8) | _SHIFTL(channelIdx, 8, 8) |
_SHIFTL(0, 0, 8),
pan);
}
// Lowest room in Ganon's Tower (Entrance Room)
if (ganonsTowerLevel == 7) {
// Adds a delay to setting the volume in the first room
sEnterGanonsTowerTimer = 2;
} else {
Audio_SetGanonsTowerBgmVolume(sGanonsTowerLevelsVol[ganonsTowerLevel % ARRAY_COUNTU(sGanonsTowerLevelsVol)]);
}
}
/**
* If a new volume is requested for ganon's tower, update the volume and
* calculate a new low-pass filter cutoff and reverb based on the new volume
*/
s32 Audio_SetGanonsTowerBgmVolume(u8 targetVol) {
u8 lowPassFilterCutoff;
u16 reverb;
u8 channelIdx;
if (sGanonsTowerVol != targetVol) {
// Sets the volume
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 0, targetVol, 2);
// Sets the filter cutoff of the form (lowPassFilterCutoff << 4) | (highPassFilter & 0xF). highPassFilter is
// always set to 0
if (targetVol < 0x40) {
// Only the first room
lowPassFilterCutoff = 1 << 4;
} else {
// Higher volume leads to a higher cut-off frequency in the low-pass filtering
lowPassFilterCutoff = (((targetVol - 0x40) >> 2) + 1) << 4;
}
// Set lowPassFilterCutoff to io port 4 from channel 15
Audio_SeqCmd8(SEQ_PLAYER_BGM_MAIN, 4, 15, lowPassFilterCutoff);
// Sets the reverb
for (channelIdx = 0; channelIdx < 16; channelIdx++) {
if (gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIdx] !=
&gAudioContext.sequenceChannelNone) {
// soundScriptIO[5] is set to 0x40 in channels 0, 1, and 4
if ((u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIdx]->soundScriptIO[5] != 0xFF) {
// Higher volume leads to lower reverb
reverb =
((u16)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIdx]->soundScriptIO[5] -
targetVol) +
0x7F;
if (reverb > 0x7F) {
reverb = 0x7F;
}
// CHAN_UPD_REVERB
Audio_QueueCmdS8(_SHIFTL(0x5, 24, 8) | _SHIFTL(SEQ_PLAYER_BGM_MAIN, 16, 8) |
_SHIFTL(channelIdx, 8, 8) | _SHIFTL(0, 0, 8),
(u8)reverb);
}
}
}
sGanonsTowerVol = targetVol;
}
return -1;
}
/**
* Responsible for lowering market bgm in Child Market Entrance and Child Market Back Alley
* Only lowers volume for 1 frame, so must be called every frame to maintain lower volume
*/
void Audio_LowerMainBgmVolume(u8 volume) {
sRiverSoundMainBgmVol = volume;
sRiverSoundMainBgmLower = true;
}
void Audio_UpdateRiverSoundVolumes(void) {
// Updates Main Bgm Volume (RiverSound of type RS_LOWER_MAIN_BGM_VOLUME)
if (sRiverSoundMainBgmLower == true) {
if (sRiverSoundMainBgmCurrentVol != sRiverSoundMainBgmVol) {
// lowers the volume for 1 frame
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 0, sRiverSoundMainBgmVol, 0xA);
sRiverSoundMainBgmCurrentVol = sRiverSoundMainBgmVol;
sRiverSoundMainBgmRestore = true;
}
sRiverSoundMainBgmLower = false;
} else if (sRiverSoundMainBgmRestore == true && D_80130608 == 0) {
// restores the volume every frame
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 0, 0x7F, 0xA);
sRiverSoundMainBgmCurrentVol = 0x7F;
sRiverSoundMainBgmRestore = false;
}
// Update Ganon's Tower Volume (RiverSound of type RS_GANON_TOWER_7)
if (sEnterGanonsTowerTimer != 0) {
sEnterGanonsTowerTimer--;
if (sEnterGanonsTowerTimer == 0) {
Audio_SetGanonsTowerBgmVolume(sGanonsTowerLevelsVol[7]);
}
}
}
void Audio_PlaySoundIncreasinglyTransposed(Vec3f* pos, s16 sfxId, u8* semitones) {
Audio_PlaySoundGeneral(sfxId, pos, 4, &gPitchFrequencies[semitones[sAudioIncreasingTranspose] + 39],
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
if (sAudioIncreasingTranspose < 15) {
sAudioIncreasingTranspose++;
}
}
void Audio_ResetIncreasingTranspose(void) {
sAudioIncreasingTranspose = 0;
}
void Audio_PlaySoundTransposed(Vec3f* pos, u16 sfxId, s8 semitone) {
Audio_PlaySoundGeneral(sfxId, pos, 4, &gPitchFrequencies[semitone + 39], &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb);
}
void func_800F4C58(Vec3f* pos, u16 sfxId, u8 arg2) {
u8 phi_s1 = 0;
u8 i;
u8 bankId;
bankId = SFX_BANK_SHIFT(sfxId);
for (i = 0; i < bankId; i++) {
phi_s1 += gChannelsPerBank[gSfxChannelLayout][i];
}
for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) {
if ((gActiveSounds[bankId][i].entryIndex != 0xFF) &&
(sfxId == gSoundBanks[bankId][gActiveSounds[bankId][i].entryIndex].sfxId)) {
Audio_QueueCmdS8(
_SHIFTL(0x6, 24, 8) | _SHIFTL(SEQ_PLAYER_SFX, 16, 8) | _SHIFTL(phi_s1, 8, 8) | _SHIFTL(6, 0, 8), arg2);
}
phi_s1++;
}
Audio_PlaySoundGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
}
void func_800F4E30(Vec3f* pos, f32 arg1) {
f32 phi_f22;
s8 phi_s4;
u8 i;
if (sSariaBgmPtr == NULL) {
sSariaBgmPtr = pos;
D_80130650 = arg1;
} else if (pos != sSariaBgmPtr) {
if (arg1 < D_80130650) {
sSariaBgmPtr = pos;
D_80130650 = arg1;
}
} else {
D_80130650 = arg1;
}
if (sSariaBgmPtr->x > 100.0f) {
phi_s4 = 0x7F;
} else if (sSariaBgmPtr->x < -100.0f) {
phi_s4 = 0;
} else {
phi_s4 = ((sSariaBgmPtr->x / 100.0f) * 64.0f) + 64.0f;
}
if (D_80130650 > 400.0f) {
phi_f22 = 0.1f;
} else if (D_80130650 < 120.0f) {
phi_f22 = 1.0f;
} else {
phi_f22 = ((1.0f - ((D_80130650 - 120.0f) / 280.0f)) * 0.9f) + 0.1f;
}
for (i = 0; i < 0x10; i++) {
if (i != 9) {
Audio_SeqCmd6(SEQ_PLAYER_BGM_MAIN, 2, i, (127.0f * phi_f22));
Audio_QueueCmdS8(0x3 << 24 | SEQ_PLAYER_BGM_MAIN << 16 | ((u8)((u32)i) << 8), phi_s4);
}
}
}
void Audio_ClearSariaBgm(void) {
if (sSariaBgmPtr != NULL) {
sSariaBgmPtr = NULL;
}
}
void Audio_ClearSariaBgmAtPos(Vec3f* pos) {
if (sSariaBgmPtr == pos) {
sSariaBgmPtr = NULL;
}
}
/**
* Turns on and off channels from both bgm players in a way that splits
* equally between the two bgm channels. Split based on note priority
*/
void Audio_SplitBgmChannels(s8 volSplit) {
u8 volume;
u8 notePriority;
u16 channelBits;
u8 bgmPlayers[2] = { SEQ_PLAYER_BGM_MAIN, SEQ_PLAYER_BGM_SUB };
u8 channelIdx;
u8 i;
if ((func_800FA0B4(SEQ_PLAYER_FANFARE) == NA_BGM_DISABLED) &&
(func_800FA0B4(SEQ_PLAYER_BGM_SUB) != NA_BGM_LONLON)) {
for (i = 0; i < ARRAY_COUNT(bgmPlayers); i++) {
if (i == 0) {
// Main Bgm SeqPlayer
volume = volSplit;
} else {
// Sub Bgm SeqPlayer
volume = 0x7F - volSplit;
}
if (volume > 100) {
notePriority = 11;
} else if (volume < 20) {
notePriority = 2;
} else {
notePriority = ((volume - 20) / 10) + 2;
}
channelBits = 0;
for (channelIdx = 0; channelIdx < 16; channelIdx++) {
if (notePriority > gAudioContext.seqPlayers[bgmPlayers[i]].channels[channelIdx]->notePriority) {
// If the note currently playing in the channel is a high enough priority,
// then keep the channel on by setting a channelBit
// If this condition fails, then the channel will be shut off
channelBits += (1 << channelIdx);
}
}
Audio_SeqCmdA(bgmPlayers[i], channelBits);
}
}
}
void Audio_PlaySariaBgm(Vec3f* pos, u16 seqId, u16 distMax) {
f32 absY;
f32 dist;
u8 vol;
f32 prevDist;
if (D_8016B9F3 != 0) {
D_8016B9F3--;
return;
}
dist = sqrtf(SQ(pos->z) + SQ(pos->x));
if (sSariaBgmPtr == NULL) {
sSariaBgmPtr = pos;
func_800F5E18(SEQ_PLAYER_BGM_SUB, seqId, 0, 7, 2);
} else {
prevDist = sqrtf(SQ(sSariaBgmPtr->z) + SQ(sSariaBgmPtr->x));
if (dist < prevDist) {
sSariaBgmPtr = pos;
} else {
dist = prevDist;
}
}
if (pos->y < 0.0f) {
absY = -pos->y;
} else {
absY = pos->y;
}
if ((distMax / 15.0f) < absY) {
vol = 0;
} else if (dist < distMax) {
vol = (1.0f - (dist / distMax)) * 127.0f;
} else {
vol = 0;
}
if (seqId != NA_BGM_GREAT_FAIRY) {
Audio_SplitBgmChannels(vol);
}
Audio_SetVolScale(SEQ_PLAYER_BGM_SUB, 3, vol, 0);
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 3, 0x7F - vol, 0);
}
void Audio_ClearSariaBgm2(void) {
sSariaBgmPtr = NULL;
}
void func_800F5510(u16 seqId) {
func_800F5550(seqId);
func_800F5E18(SEQ_PLAYER_BGM_MAIN, seqId, 0, 0, 1);
}
void func_800F5550(u16 seqId) {
u8 sp27 = 0;
u16 nv;
if (func_800FA0B4(SEQ_PLAYER_BGM_MAIN) != NA_BGM_WINDMILL) {
if (func_800FA0B4(SEQ_PLAYER_BGM_SUB) == NA_BGM_LONLON) {
func_800F9474(SEQ_PLAYER_BGM_SUB, 0);
Audio_QueueCmdS32(0xF8000000, 0);
}
if ((sSeqFlags[D_80130630] & 0x20) && sSeqFlags[(seqId & 0xFF) & 0xFF] & 0x10) {
if ((D_8013062C & 0x3F) != 0) {
sp27 = 0x1E;
}
func_800F5E18(SEQ_PLAYER_BGM_MAIN, seqId, sp27, 7, D_8013062C);
D_8013062C = 0;
} else {
nv = (sSeqFlags[(seqId & 0xFF) & 0xFF] & 0x40) ? 1 : 0xFF;
func_800F5E18(SEQ_PLAYER_BGM_MAIN, seqId, 0, 7, nv);
if (!(sSeqFlags[seqId] & 0x20)) {
D_8013062C = 0xC0;
}
}
D_80130630 = seqId & 0xFF;
}
}
void func_800F56A8(void) {
u16 temp_v0;
u8 bvar;
temp_v0 = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
bvar = temp_v0 & 0xFF;
if ((temp_v0 != NA_BGM_DISABLED) && (sSeqFlags[bvar] & 0x10)) {
if (D_8013062C != 0xC0) {
D_8013062C = gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[3];
} else {
D_8013062C = 0;
}
}
}
void func_800F5718(void) {
if (func_800FA0B4(SEQ_PLAYER_BGM_MAIN) != NA_BGM_WINDMILL) {
Audio_StartSeq(SEQ_PLAYER_BGM_MAIN, 0, NA_BGM_WINDMILL);
}
}
void func_800F574C(f32 arg0, u8 arg2) {
if (arg0 == 1.0f) {
Audio_SeqCmdB40(SEQ_PLAYER_BGM_MAIN, arg2, 0);
} else {
Audio_SeqCmdC(SEQ_PLAYER_FANFARE, 0x30, arg2, arg0 * 100.0f);
}
Audio_SeqCmdC(SEQ_PLAYER_FANFARE, 0xA0, arg2, arg0 * 100.0f);
}
void func_800F5918(void) {
if (func_800FA0B4(SEQ_PLAYER_BGM_MAIN) == NA_BGM_TIMED_MINI_GAME && func_800FA11C(0, 0xF0000000)) {
Audio_SeqCmdB(SEQ_PLAYER_BGM_MAIN, 5, 0, 0xD2);
}
}
void func_800F595C(u16 arg0) {
u8 arg0b = arg0 & 0xFF;
if (sSeqFlags[arg0b] & 2) {
Audio_PlayFanfare(arg0);
} else if (sSeqFlags[arg0b] & 4) {
Audio_StartSeq(SEQ_PLAYER_FANFARE, 0, arg0);
} else {
func_800F5E18(SEQ_PLAYER_BGM_MAIN, arg0, 0, 7, -1);
Audio_SeqCmd1(SEQ_PLAYER_FANFARE, 0);
}
}
void func_800F59E8(u16 arg0) {
u8 arg0b = arg0 & 0xFF;
if (sSeqFlags[arg0b] & 2) {
Audio_SeqCmd1(SEQ_PLAYER_FANFARE, 0);
} else if (sSeqFlags[arg0b] & 4) {
Audio_SeqCmd1(SEQ_PLAYER_FANFARE, 0);
} else {
Audio_SeqCmd1(SEQ_PLAYER_BGM_MAIN, 0);
}
}
s32 func_800F5A58(u8 arg0) {
u8 phi_a1 = 0;
if (sSeqFlags[arg0 & 0xFF] & 2) {
phi_a1 = 1;
} else if (sSeqFlags[arg0 & 0xFF] & 4) {
phi_a1 = 1;
}
if (arg0 == (u8)func_800FA0B4(phi_a1)) {
return 1;
} else {
return 0;
}
}
/**
* Plays a sequence on the main bgm player, but stores the previous sequence to return to later
* Designed for the mini-boss sequence, but also used by mini-game 2 sequence
*/
void func_800F5ACC(u16 seqId) {
u16 curSeqId = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
if ((curSeqId & 0xFF) != NA_BGM_GANON_TOWER && (curSeqId & 0xFF) != NA_BGM_ESCAPE && curSeqId != seqId) {
Audio_SetSequenceMode(SEQ_MODE_IGNORE);
if (curSeqId != NA_BGM_DISABLED) {
sPrevMainBgmSeqId = curSeqId;
} else {
osSyncPrintf("Middle Boss BGM Start not stack \n");
}
Audio_StartSeq(SEQ_PLAYER_BGM_MAIN, 0, seqId);
}
}
/**
* Restores the previous sequence to the main bgm player before func_800F5ACC was called
*/
void func_800F5B58(void) {
if ((func_800FA0B4(SEQ_PLAYER_BGM_MAIN) != NA_BGM_DISABLED) && (sPrevMainBgmSeqId != NA_BGM_DISABLED) &&
(sSeqFlags[func_800FA0B4(SEQ_PLAYER_BGM_MAIN) & 0xFF] & 8)) {
if (sPrevMainBgmSeqId == NA_BGM_DISABLED) {
Audio_SeqCmd1(SEQ_PLAYER_BGM_MAIN, 0);
} else {
Audio_StartSeq(SEQ_PLAYER_BGM_MAIN, 0, sPrevMainBgmSeqId);
}
sPrevMainBgmSeqId = NA_BGM_DISABLED;
}
}
/**
* Plays the nature ambience sequence on the main bgm player, but stores the previous sequence to return to later
*/
void func_800F5BF0(u8 natureAmbienceId) {
u16 curSeqId = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
if (curSeqId != NA_BGM_NATURE_AMBIENCE) {
sPrevMainBgmSeqId = curSeqId;
}
Audio_PlayNatureAmbienceSequence(natureAmbienceId);
}
/**
* Restores the previous sequence to the main bgm player before func_800F5BF0 was called
*/
void func_800F5C2C(void) {
if (sPrevMainBgmSeqId != NA_BGM_DISABLED) {
Audio_StartSeq(SEQ_PLAYER_BGM_MAIN, 0, sPrevMainBgmSeqId);
}
sPrevMainBgmSeqId = NA_BGM_DISABLED;
}
void Audio_PlayFanfare(u16 seqId) {
u16 sp26;
u32 sp20;
u8* sp1C;
u8* sp18;
sp26 = func_800FA0B4(SEQ_PLAYER_FANFARE);
sp1C = func_800E5E84(sp26 & 0xFF, &sp20);
sp18 = func_800E5E84(seqId & 0xFF, &sp20);
if ((sp26 == NA_BGM_DISABLED) || (*sp1C == *sp18)) {
D_8016B9F4 = 1;
} else {
D_8016B9F4 = 5;
Audio_SeqCmd1(SEQ_PLAYER_FANFARE, 0);
}
D_8016B9F6 = seqId;
}
void func_800F5CF8(void) {
u16 sp26;
u16 pad;
u16 sp22;
if (D_8016B9F4 != 0) {
D_8016B9F4--;
if (D_8016B9F4 == 0) {
Audio_QueueCmdS32(0xE3000000, SEQUENCE_TABLE);
Audio_QueueCmdS32(0xE3000000, FONT_TABLE);
func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
sp26 = func_800FA0B4(SEQ_PLAYER_FANFARE);
sp22 = func_800FA0B4(SEQ_PLAYER_BGM_SUB);
if (sp26 == NA_BGM_DISABLED) {
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 1, 0, 5);
Audio_SetVolScale(SEQ_PLAYER_BGM_SUB, 1, 0, 5);
Audio_SeqCmdC(SEQ_PLAYER_FANFARE, 0x80, 1, 0xA);
Audio_SeqCmdC(SEQ_PLAYER_FANFARE, 0x83, 1, 0xA);
Audio_SeqCmdC(SEQ_PLAYER_FANFARE, 0x90, 0, 0);
if (sp22 != NA_BGM_LONLON) {
Audio_SeqCmdC(SEQ_PLAYER_FANFARE, 0x93, 0, 0);
}
}
Audio_StartSeq(SEQ_PLAYER_FANFARE, 1, D_8016B9F6);
Audio_SeqCmdA(0, 0xFFFF);
if (sp22 != NA_BGM_LONLON) {
Audio_SeqCmdA(SEQ_PLAYER_BGM_SUB, 0xFFFF);
}
}
}
}
void func_800F5E18(u8 playerIdx, u16 seqId, u8 fadeTimer, s8 arg3, s8 arg4) {
Audio_SeqCmd7(playerIdx, arg3, arg4);
Audio_StartSeq(playerIdx, fadeTimer, seqId);
}
void Audio_SetSequenceMode(u8 seqMode) {
s32 volumeFadeInTimer;
u16 seqId;
u8 volumeFadeOutTimer;
sSeqModeInput = seqMode;
if (sPrevMainBgmSeqId == NA_BGM_DISABLED) {
if (sAudioCutsceneFlag) {
seqMode = SEQ_MODE_IGNORE;
}
seqId = D_8016E750[SEQ_PLAYER_BGM_MAIN].unk_254;
if (seqId == NA_BGM_FIELD_LOGIC && func_800FA0B4(SEQ_PLAYER_BGM_SUB) == (NA_BGM_ENEMY | 0x800)) {
seqMode = SEQ_MODE_IGNORE;
}
if ((seqId == NA_BGM_DISABLED) || (sSeqFlags[(u8)(seqId & 0xFF)] & 1) ||
((sPrevSeqMode & 0x7F) == SEQ_MODE_ENEMY)) {
if (seqMode != (sPrevSeqMode & 0x7F)) {
if (seqMode == SEQ_MODE_ENEMY) {
// Start playing enemy bgm
if (D_8016E750[SEQ_PLAYER_BGM_SUB].volScales[1] - sAudioEnemyVol < 0) {
volumeFadeInTimer = -(D_8016E750[SEQ_PLAYER_BGM_SUB].volScales[1] - sAudioEnemyVol);
} else {
volumeFadeInTimer = D_8016E750[SEQ_PLAYER_BGM_SUB].volScales[1] - sAudioEnemyVol;
}
Audio_SetVolScale(SEQ_PLAYER_BGM_SUB, 3, sAudioEnemyVol, volumeFadeInTimer);
Audio_StartSeq(SEQ_PLAYER_BGM_SUB, 10, NA_BGM_ENEMY | 0x800);
if (seqId != NA_BGM_NATURE_AMBIENCE) {
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 3, (0x7F - sAudioEnemyVol) & 0xFF, 0xA);
Audio_SplitBgmChannels(sAudioEnemyVol);
}
} else if ((sPrevSeqMode & 0x7F) == SEQ_MODE_ENEMY) {
// Stop playing enemy bgm
Audio_SeqCmd1(SEQ_PLAYER_BGM_SUB, 10);
if (seqMode == SEQ_MODE_IGNORE) {
volumeFadeOutTimer = 0;
} else {
volumeFadeOutTimer = 10;
}
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 3, 0x7F, volumeFadeOutTimer);
Audio_SplitBgmChannels(0);
}
sPrevSeqMode = seqMode + 0x80;
}
} else {
// Hyrule Field will play slightly different bgm music depending on whether player is standing
// still or moving. This is the logic to determine the transition between those two states
if (seqMode == SEQ_MODE_DEFAULT) {
if (sPrevSeqMode == SEQ_MODE_STILL) {
sNumFramesMoving = 0;
}
sNumFramesStill = 0;
sNumFramesMoving++;
} else {
sNumFramesStill++;
}
if (seqMode == SEQ_MODE_STILL && sNumFramesStill < 30 && sNumFramesMoving > 20) {
seqMode = SEQ_MODE_DEFAULT;
}
sPrevSeqMode = seqMode;
Audio_SeqCmd7(SEQ_PLAYER_BGM_MAIN, 2, seqMode);
}
}
}
void Audio_SetBgmEnemyVolume(f32 dist) {
f32 adjDist;
if (sPrevSeqMode == (0x80 | SEQ_MODE_ENEMY)) {
if (dist != sAudioEnemyDist) {
if (dist < 150.0f) {
adjDist = 0.0f;
} else if (dist > 500.0f) {
adjDist = 350.0f;
} else {
adjDist = dist - 150.0f;
}
sAudioEnemyVol = ((350.0f - adjDist) * 127.0f) / 350.0f;
Audio_SetVolScale(SEQ_PLAYER_BGM_SUB, 3, sAudioEnemyVol, 10);
if (D_8016E750[SEQ_PLAYER_BGM_MAIN].unk_254 != NA_BGM_NATURE_AMBIENCE) {
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 3, (0x7F - sAudioEnemyVol), 10);
}
}
if (D_8016E750[SEQ_PLAYER_BGM_MAIN].unk_254 != NA_BGM_NATURE_AMBIENCE) {
Audio_SplitBgmChannels(sAudioEnemyVol);
}
}
sAudioEnemyDist = dist;
}
void func_800F6268(f32 dist, u16 arg1) {
s8 pad;
s8 phi_v1;
s16 temp_a0;
sAudioHasMalonBgm = true;
sAudioMalonBgmDist = dist;
if (D_8016B9F2 == 0) {
temp_a0 = (s8)(func_800FA0B4(SEQ_PLAYER_BGM_MAIN) & 0xFF);
if (temp_a0 == (arg1 & 0xFF)) {
if ((arg1 & 0xFF) == NA_BGM_LONLON) {
if (dist > 2000.0f) {
phi_v1 = 127;
} else if (dist < 200.0f) {
phi_v1 = 0;
} else {
phi_v1 = (s8)(((dist - 200.0f) * 127.0f) / 1800.0f);
}
// Transition volume of channels 0, 1 and 13 on seq player 0 over 3 frames
Audio_SeqCmd6(SEQ_PLAYER_BGM_MAIN, 3, 0, 127 - phi_v1);
Audio_SeqCmd6(SEQ_PLAYER_BGM_MAIN, 3, 1, 127 - phi_v1);
Audio_SeqCmd6(SEQ_PLAYER_BGM_MAIN, 3, 13, phi_v1);
if (D_8016B9D8 == 0) {
D_8016B9D8++;
}
}
} else if ((temp_a0 == NA_BGM_NATURE_AMBIENCE) && ((arg1 & 0xFF) == NA_BGM_LONLON)) {
temp_a0 = (s8)(func_800FA0B4(SEQ_PLAYER_BGM_SUB) & 0xFF);
if ((temp_a0 != (arg1 & 0xFF)) && (D_8016B9D8 < 10)) {
func_800F5E18(SEQ_PLAYER_BGM_SUB, NA_BGM_LONLON, 0, 0, 0);
Audio_SeqCmdA(SEQ_PLAYER_BGM_SUB, 0xFFFC);
D_8016B9D8 = 10;
}
if (dist > 2000.0f) {
phi_v1 = 127;
} else if (dist < 200.0f) {
phi_v1 = 0;
} else {
phi_v1 = (s8)(((dist - 200.0f) * 127.0f) / 1800.0f);
}
// Transition volume of channels 0 and 1 on seq player 0 over 3 frames
Audio_SeqCmd6(SEQ_PLAYER_BGM_SUB, 3, 0, 127 - phi_v1);
Audio_SeqCmd6(SEQ_PLAYER_BGM_SUB, 3, 1, 127 - phi_v1);
}
if (D_8016B9D8 < 10) {
D_8016B9D8++;
}
}
}
void func_800F64E0(u8 arg0) {
D_80130608 = arg0;
if (arg0 != 0) {
Audio_PlaySoundGeneral(NA_SE_SY_WIN_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
Audio_QueueCmdS32(0xF1000000, 0);
} else {
Audio_PlaySoundGeneral(NA_SE_SY_WIN_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
Audio_QueueCmdS32(0xF2000000, 0);
}
}
void func_800F6584(u8 arg0) {
u8 playerIdx;
u16 sp34;
D_8016B9F2 = arg0;
if ((func_800FA0B4(SEQ_PLAYER_BGM_MAIN) & 0xFF) == NA_BGM_LONLON) {
playerIdx = SEQ_PLAYER_BGM_MAIN;
sp34 = 0;
} else if ((func_800FA0B4(SEQ_PLAYER_BGM_SUB) & 0xFF) == NA_BGM_LONLON) {
playerIdx = SEQ_PLAYER_BGM_SUB;
sp34 = 0xFFFC;
} else {
return;
}
if (arg0 != 0) {
Audio_SeqCmd6(playerIdx, 1, 0, 0);
Audio_SeqCmd6(playerIdx, 1, 1, 0);
if (playerIdx == SEQ_PLAYER_BGM_SUB) {
Audio_SeqCmdA(playerIdx, sp34 | 3);
}
} else {
if (playerIdx == SEQ_PLAYER_BGM_SUB) {
func_800F5E18(SEQ_PLAYER_BGM_SUB, NA_BGM_LONLON, 0, 0, 0);
}
Audio_SeqCmd6(playerIdx, 1, 0, 0x7F);
Audio_SeqCmd6(playerIdx, 1, 1, 0x7F);
if (playerIdx == SEQ_PLAYER_BGM_SUB) {
Audio_SeqCmdA(playerIdx, sp34);
}
}
}
void Audio_SetEnvReverb(s8 reverb) {
sAudioEnvReverb = reverb & 0x7F;
}
void Audio_SetCodeReverb(s8 reverb) {
if (reverb != 0) {
sAudioCodeReverb = reverb & 0x7F;
}
}
void func_800F6700(s8 arg0) {
s8 sp1F;
switch (arg0) {
case 0:
sp1F = 0;
D_80130604 = 0;
break;
case 1:
sp1F = 3;
D_80130604 = 3;
break;
case 2:
sp1F = 1;
D_80130604 = 1;
break;
case 3:
sp1F = 0;
D_80130604 = 2;
break;
}
Audio_SeqCmdE0(SEQ_PLAYER_BGM_MAIN, sp1F);
}
void Audio_SetBaseFilter(u8 filter) {
if (sAudioBaseFilter != filter) {
if (filter == 0) {
Audio_StopSfxById(NA_SE_PL_IN_BUBBLE);
} else if (sAudioBaseFilter == 0) {
Audio_PlaySoundGeneral(NA_SE_PL_IN_BUBBLE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
}
}
sAudioBaseFilter = filter;
sAudioBaseFilter2 = filter;
}
void Audio_SetExtraFilter(u8 filter) {
u32 t;
u8 i;
sAudioExtraFilter2 = filter;
sAudioExtraFilter = filter;
if (D_8016E750[SEQ_PLAYER_BGM_MAIN].unk_254 == NA_BGM_NATURE_AMBIENCE) {
for (i = 0; i < 16; i++) {
t = i;
// CHAN_UPD_SCRIPT_IO (seq player 0, all channels, slot 6)
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_BGM_MAIN << 16 | ((t & 0xFF) << 8) | 6, filter);
}
}
}
void Audio_SetCutsceneFlag(s8 flag) {
sAudioCutsceneFlag = flag;
}
void Audio_PlaySoundGeneralIfNotInCutscene(u16 sfxId, Vec3f* pos, u8 arg2, f32* freqScale, f32* arg4, s8* reverbAdd) {
if (!sAudioCutsceneFlag) {
Audio_PlaySoundGeneral(sfxId, pos, arg2, freqScale, arg4, reverbAdd);
}
}
void Audio_PlaySoundIfNotInCutscene(u16 sfxId) {
Audio_PlaySoundGeneralIfNotInCutscene(sfxId, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
}
void func_800F6964(u16 arg0) {
s32 skip;
u8 channelIdx;
Audio_SeqCmd1(SEQ_PLAYER_BGM_MAIN, (arg0 * 3) / 2);
Audio_SeqCmd1(SEQ_PLAYER_FANFARE, (arg0 * 3) / 2);
for (channelIdx = 0; channelIdx < 16; channelIdx++) {
skip = false;
switch (channelIdx) {
case SFX_CHANNEL_SYSTEM0:
case SFX_CHANNEL_SYSTEM1:
if (gAudioSpecId == 10) {
skip = true;
}
break;
case SFX_CHANNEL_OCARINA:
skip = true;
break;
}
if (!skip) {
Audio_SeqCmd6(SEQ_PLAYER_SFX, arg0 >> 1, channelIdx, 0);
}
}
Audio_SeqCmd1(SEQ_PLAYER_BGM_SUB, (arg0 * 3) / 2);
}
void func_800F6AB0(u16 arg0) {
Audio_SeqCmd1(SEQ_PLAYER_BGM_MAIN, arg0);
Audio_SeqCmd1(SEQ_PLAYER_FANFARE, arg0);
Audio_SeqCmd1(SEQ_PLAYER_BGM_SUB, arg0);
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 3, 0x7F, 0);
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 1, 0x7F, 0);
}
void func_800F6B3C(void) {
func_800F9280(SEQ_PLAYER_SFX, 0, 0xFF, 5);
}
void Audio_DisableAllSeq(void) {
Audio_DisableSeq(SEQ_PLAYER_BGM_MAIN, 0);
Audio_DisableSeq(SEQ_PLAYER_FANFARE, 0);
Audio_DisableSeq(SEQ_PLAYER_SFX, 0);
Audio_DisableSeq(SEQ_PLAYER_BGM_SUB, 0);
Audio_ScheduleProcessCmds();
}
s8 func_800F6BB8(void) {
return func_800E6680();
}
void func_800F6BDC(void) {
Audio_DisableAllSeq();
Audio_ScheduleProcessCmds();
while (true) {
if (!func_800F6BB8()) {
return;
}
}
}
void Audio_PreNMI(void) {
Audio_PreNMIInternal();
}
void func_800F6C34(void) {
sPrevSeqMode = 0;
D_8016B7A8 = 1.0f;
D_8016B7B0 = 1.0f;
sAudioBaseFilter = 0;
sAudioExtraFilter = 0;
sAudioBaseFilter2 = 0;
sAudioExtraFilter2 = 0;
AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF);
sRiverFreqScaleLerp.remainingFrames = 0;
sWaterfallFreqScaleLerp.remainingFrames = 0;
sRiverFreqScaleLerp.value = 1.0f;
sWaterfallFreqScaleLerp.value = 1.0f;
D_8016B7D8 = 1.0f;
sRiverSoundMainBgmVol = 0x7F;
sRiverSoundMainBgmCurrentVol = 0x7F;
sRiverSoundMainBgmLower = false;
sRiverSoundMainBgmRestore = false;
sGanonsTowerVol = 0xFF;
D_8016B9D8 = 0;
sSpecReverb = sSpecReverbs[gAudioSpecId];
D_80130608 = 0;
sPrevMainBgmSeqId = NA_BGM_DISABLED;
Audio_QueueCmdS8(0x46 << 24 | SEQ_PLAYER_BGM_MAIN << 16, -1);
sSariaBgmPtr = NULL;
D_8016B9F4 = 0;
D_8016B9F3 = 1;
D_8016B9F2 = 0;
}
void Audio_SetNatureAmbienceChannelIO(u8 channelIdxRange, u8 port, u8 val) {
u8 firstChannelIdx;
u8 lastChannelIdx;
u8 channelIdx;
if ((D_8016E750[SEQ_PLAYER_BGM_MAIN].unk_254 != NA_BGM_NATURE_AMBIENCE) && func_800FA11C(1, 0xF00000FF)) {
sAudioNatureFailed = true;
return;
}
// channelIdxRange = 01 on port 1
if (((channelIdxRange << 8) + port) == ((NATURE_CHANNEL_CRITTER_0 << 8) + CHANNEL_IO_PORT_1)) {
if (func_800FA0B4(SEQ_PLAYER_BGM_SUB) != NA_BGM_LONLON) {
D_8016B9D8 = 0;
}
}
firstChannelIdx = channelIdxRange >> 4;
lastChannelIdx = channelIdxRange & 0xF;
if (firstChannelIdx == 0) {
firstChannelIdx = channelIdxRange & 0xF;
}
for (channelIdx = firstChannelIdx; channelIdx <= lastChannelIdx; channelIdx++) {
Audio_SeqCmd8(SEQ_PLAYER_BGM_MAIN, port, channelIdx, val);
}
}
void Audio_StartNatureAmbienceSequence(u16 playerIO, u16 channelMask) {
u8 channelIdx;
if (func_800FA0B4(SEQ_PLAYER_BGM_MAIN) == NA_BGM_WINDMILL) {
func_800F3F3C(0xF);
return;
}
Audio_SeqCmd7(SEQ_PLAYER_BGM_MAIN, 0, 1);
Audio_SeqCmd7(SEQ_PLAYER_BGM_MAIN, 4, playerIO >> 8);
Audio_SeqCmd7(SEQ_PLAYER_BGM_MAIN, 5, playerIO & 0xFF);
Audio_SetVolScale(SEQ_PLAYER_BGM_MAIN, 0, 0x7F, 1);
channelIdx = false;
if (D_80133408 != 0) {
channelIdx = true;
Audio_SeqCmdE01(SEQ_PLAYER_BGM_MAIN, 0);
}
Audio_StartSeq(SEQ_PLAYER_BGM_MAIN, 0, NA_BGM_NATURE_AMBIENCE);
if (channelIdx) {
Audio_SeqCmdE01(SEQ_PLAYER_BGM_MAIN, 1);
}
for (channelIdx = 0; channelIdx < 16; channelIdx++) {
if (!(channelMask & (1 << channelIdx)) && (playerIO & (1 << channelIdx))) {
Audio_SeqCmd8(SEQ_PLAYER_BGM_MAIN, CHANNEL_IO_PORT_1, channelIdx, 1);
}
}
}
void Audio_PlayNatureAmbienceSequence(u8 natureAmbienceId) {
u8 i = 0;
u8 channelIdx;
u8 port;
u8 val;
if ((D_8016E750[SEQ_PLAYER_BGM_MAIN].unk_254 == NA_BGM_DISABLED) ||
!(sSeqFlags[((u8)D_8016E750[SEQ_PLAYER_BGM_MAIN].unk_254) & 0xFF] & 0x80)) {
Audio_StartNatureAmbienceSequence(sNatureAmbienceDataIO[natureAmbienceId].playerIO,
sNatureAmbienceDataIO[natureAmbienceId].channelMask);
while ((sNatureAmbienceDataIO[natureAmbienceId].channelIO[i] != 0xFF) && (i < 100)) {
// Probably a fake match, using Audio_SeqCmd8 doesn't work.
channelIdx = sNatureAmbienceDataIO[natureAmbienceId].channelIO[i++];
port = sNatureAmbienceDataIO[natureAmbienceId].channelIO[i++];
val = sNatureAmbienceDataIO[natureAmbienceId].channelIO[i++];
Audio_QueueSeqCmd(0x80000000 | (SEQ_PLAYER_BGM_MAIN << 24) | (port << 0x10) | (channelIdx << 8) | val);
}
Audio_SeqCmd8(SEQ_PLAYER_BGM_MAIN, CHANNEL_IO_PORT_7, NATURE_CHANNEL_UNK, D_80130604);
}
}
void Audio_Init(void) {
AudioLoad_Init(NULL, 0);
}
void Audio_InitSound(void) {
func_800F6C34();
AudioOcarina_ResetStaffs();
Audio_ResetSfxChannelState();
func_800FAEB4();
Audio_ResetSounds();
func_800F9280(SEQ_PLAYER_SFX, 0, 0x70, 10);
}
void func_800F7170(void) {
func_800F9280(SEQ_PLAYER_SFX, 0, 0x70, 1);
Audio_QueueCmdS32(0xF2000000, 1);
Audio_ScheduleProcessCmds();
Audio_QueueCmdS32(0xF8000000, 0);
}
void func_800F71BC(s32 arg0) {
D_80133418 = 1;
func_800F6C34();
AudioOcarina_ResetStaffs();
Audio_ResetSfxChannelState();
func_800FADF8();
Audio_ResetSounds();
}
void func_800F7208(void) {
func_800FADF8();
Audio_QueueCmdS32(0xF2000000, 1);
func_800F6C34();
Audio_ResetSfxChannelState();
func_800F9280(SEQ_PLAYER_SFX, 0, 0x70, 1);
}