diff options
| author | Tyler McGavran <tyler.taggerung@gmail.com> | 2022-11-06 10:24:24 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-06 08:24:24 -0700 |
| commit | e9415164bb5786f0f5052f92d59843d6549b79e4 (patch) | |
| tree | 2ca31c2211890441d74afdd19ef7a2d6eb5d7ca3 /src | |
| parent | 4e5946257d8049f421c4247d6039de94d3db83d5 (diff) | |
Lots and lots of audio code copied from SM64 (#270)
* Lots of audio decomp
* effects and playback are 100% matched
* Took some notes from the SM64 Makefile to get the right compiler
options for a couple files
* Added the audio files to rename_symbol utility
Signed-off-by: Taggerung <tyler.taggerung@gmail.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio/data.c | 4 | ||||
| -rw-r--r-- | src/audio/data.h | 24 | ||||
| -rw-r--r-- | src/audio/effects.c | 660 | ||||
| -rw-r--r-- | src/audio/effects.h | 12 | ||||
| -rw-r--r-- | src/audio/external.c | 24 | ||||
| -rw-r--r-- | src/audio/external.h | 16 | ||||
| -rw-r--r-- | src/audio/heap.c | 1316 | ||||
| -rw-r--r-- | src/audio/heap.h | 99 | ||||
| -rw-r--r-- | src/audio/internal.h | 494 | ||||
| -rw-r--r-- | src/audio/load.c | 567 | ||||
| -rw-r--r-- | src/audio/load.h | 28 | ||||
| -rw-r--r-- | src/audio/playback.c | 1715 | ||||
| -rw-r--r-- | src/audio/playback.h | 49 | ||||
| -rw-r--r-- | src/audio/port_eu.c | 98 | ||||
| -rw-r--r-- | src/audio/port_eu.h | 7 | ||||
| -rw-r--r-- | src/audio/seqplayer.c | 2476 | ||||
| -rw-r--r-- | src/audio/seqplayer.h | 41 | ||||
| -rw-r--r-- | src/audio/synthesis.c | 1279 | ||||
| -rw-r--r-- | src/audio/synthesis.h | 26 |
19 files changed, 4090 insertions, 4845 deletions
diff --git a/src/audio/data.c b/src/audio/data.c index c0e12c35f..25f05a007 100644 --- a/src/audio/data.c +++ b/src/audio/data.c @@ -346,8 +346,8 @@ struct AdsrEnvelope gDefaultEnvelope[] = { // TODO 0x00000000800f624c fill2 u32 fill2 = 0x00000000; -struct NoteSub gZeroNoteSub = { 0 }; -struct NoteSub gDefaultNoteSub = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { NULL } }; +struct NoteSubEu gZeroNoteSub = { 0 }; +struct NoteSubEu gDefaultNoteSub = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { NULL } }; u16 gHeadsetPanQuantization[0x10] = { 0x40, 0x40, 0x30, 0x30, 0x20, 0x20, 0x10, 0, 0, 0, diff --git a/src/audio/data.h b/src/audio/data.h index 9dddc3e81..dd87947a4 100644 --- a/src/audio/data.h +++ b/src/audio/data.h @@ -7,9 +7,29 @@ #define AUDIO_LOCK_NOT_LOADING 0x76557364 #define AUDIO_LOCK_LOADING 0x19710515 -extern struct AdsrEnvelope gDefaultEnvelope[3]; - // number of DMAs performed during this frame extern s32 gCurrAudioFrameDmaCount; +extern s16 sSawtoothWaves[256]; +extern s16 sTriangleWaves[256]; +extern s16 sSineWaves[256]; +extern s16 sSquareWaves[256]; +extern s16 sUnknownWave6[256]; +extern s16 gUnknownWave7[256]; +extern s16 *gWaveSamples[6]; +extern u32 fill[2]; +extern f32 gPitchBendFrequencyScale[256]; +extern f32 gNoteFrequencies[128]; +extern u8 gDefaultShortNoteVelocityTable[16]; +extern u8 gDefaultShortNoteDurationTable[16]; +extern struct AdsrEnvelope gDefaultEnvelope[]; +extern u32 fill2; +extern struct NoteSubEu gZeroNoteSub; +extern struct NoteSubEu gDefaultNoteSub; +extern u16 gHeadsetPanQuantization[0x10]; +extern s32 gUnknownData_800F6290[32]; +extern f32 gHeadsetPanVolume[128]; +extern f32 gStereoPanVolume[128]; +extern f32 gDefaultPanVolume[128]; + #endif diff --git a/src/audio/effects.c b/src/audio/effects.c index f12a4c0e4..d8003ef1a 100644 --- a/src/audio/effects.c +++ b/src/audio/effects.c @@ -1,433 +1,325 @@ #include <ultra64.h> #include <macros.h> -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BDE50(void *arg0, s32 arg1) { - f32 temp_f0; - s32 temp_a2; - u32 temp_v0_2; - void *temp_v0; - void *temp_v1; - f32 phi_f0; - void *phi_a3; - s32 phi_a2; - - phi_a3 = arg0; - phi_a2 = 0; - if (((arg0->unk0 << 9) < 0) || (arg1 != 0)) { - temp_v0 = arg0->unk44; - temp_f0 = arg0->unk24 * arg0->unk20 * temp_v0->unk2C; - phi_f0 = temp_f0; - if (((temp_v0->unk0 * 4) < 0) && ((arg0->unk3 & 0x20) != 0)) { - phi_f0 = temp_v0->unk24 * temp_f0; +#include "audio/seqplayer.h" +#include "audio/effects.h" +#include "audio/internal.h" +#include "audio/load.h" +#include "audio/data.h" + +void sequence_channel_process_sound(struct SequenceChannel *seqChannel, s32 recalculateVolume) { + f32 channelVolume; + s32 i; + + if (seqChannel->changes.as_bitfields.volume || recalculateVolume) { + channelVolume = seqChannel->volume * seqChannel->volumeScale * seqChannel->seqPlayer->appliedFadeVolume; + if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) { + channelVolume = seqChannel->seqPlayer->muteVolumeScale * channelVolume; } - arg0->unk2C = phi_f0 * phi_f0; + seqChannel->appliedVolume = channelVolume * channelVolume; } - if (arg0->unk0 & 0x200000) { - arg0->unk28 = arg0->unk9 * arg0->unkA; + + if (seqChannel->changes.as_bitfields.pan) { + seqChannel->pan = seqChannel->newPan * seqChannel->panChannelWeight; } - do { - temp_v1 = phi_a3->unk48; - temp_a2 = phi_a2 + 4; - phi_a2 = temp_a2; - if (temp_v1 != 0) { - temp_v0_2 = temp_v1->unk0; - if (((temp_v0_2 >> 0x1F) != 0) && (temp_v1->unk40 != 0)) { - if (temp_v0_2 & 0x4000000) { - temp_v1->unk30 = temp_v1->unk24 * arg0->unk30; - temp_v1->unk2C = temp_v1->unk28 * arg0->unk2C; - temp_v1->unk0 = temp_v1->unk0 & 0xFFFB; - temp_v1->unk6 = (arg0->unk28 + (temp_v1->unk5 * (0x80 - arg0->unkA))) >> 7; - } else { - if (arg0->unk1 < 0) { - temp_v1->unk30 = temp_v1->unk24 * arg0->unk30; - } - if (((arg0->unk0 << 9) < 0) || (arg1 != 0)) { - temp_v1->unk2C = temp_v1->unk28 * arg0->unk2C; - } - if (arg0->unk0 & 0x200000) { - temp_v1->unk6 = (arg0->unk28 + (temp_v1->unk5 * (0x80 - arg0->unkA))) >> 7; - } + + for (i = 0; i < 4; ++i) { + struct SequenceChannelLayer *layer = seqChannel->layers[i]; + if (layer != NULL && layer->enabled && layer->note != NULL) { + if (layer->notePropertiesNeedInit) { + layer->noteFreqScale = layer->freqScale * seqChannel->freqScale; + layer->noteVelocity = layer->velocitySquare * seqChannel->appliedVolume; + layer->notePan = (seqChannel->pan + layer->pan * (0x80 - seqChannel->panChannelWeight)) >> 7; + layer->notePropertiesNeedInit = FALSE; + } else { + if (seqChannel->changes.as_bitfields.freqScale) { + layer->noteFreqScale = layer->freqScale * seqChannel->freqScale; + } + if (seqChannel->changes.as_bitfields.volume || recalculateVolume) { + layer->noteVelocity = layer->velocitySquare * seqChannel->appliedVolume; + } + if (seqChannel->changes.as_bitfields.pan) { + layer->notePan = (seqChannel->pan + layer->pan * (0x80 - seqChannel->panChannelWeight)) >> 7; } } } - phi_a3 += 4; - } while (temp_a2 != 0x10); - arg0->unk1 = 0; + } + seqChannel->changes.as_u8 = 0; } -#else -GLOBAL_ASM("asm/non_matchings/audio/effects/func_800BDE50.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BDE50(s32, u32); // extern -void func_800BEF2C(void *); // extern -extern ? D_803B5EF0; - -void func_800BDFF8(void *arg0) { - s32 temp_a0; - s32 temp_s0; - u16 temp_t1; - void *phi_s1; - s32 phi_s0; - - if (arg0->unk10 != 0) { - arg0->unk18 = arg0->unk18 + arg0->unk1C; - arg0->unk0 = arg0->unk0 | 4; - if (arg0->unk18 > 1.0f) { - arg0->unk18 = 1.0f; + +void sequence_player_process_sound(struct SequencePlayer *seqPlayer) { + s32 i; + + if (seqPlayer->fadeRemainingFrames != 0) { + seqPlayer->fadeVolume += seqPlayer->fadeVelocity; + seqPlayer->recalculateVolume = TRUE; + + if (seqPlayer->fadeVolume > US_FLOAT2(1)) { + seqPlayer->fadeVolume = US_FLOAT2(1); } - if (arg0->unk18 < 0.0f) { - arg0->unk18 = 0.0f; + if (seqPlayer->fadeVolume < 0) { + seqPlayer->fadeVolume = 0; } - temp_t1 = arg0->unk10 - 1; - arg0->unk10 = temp_t1; - if (((temp_t1 & 0xFFFF) == 0) && (arg0->unk1 == 2)) { - func_800BEF2C(arg0); - return; + + if (--seqPlayer->fadeRemainingFrames == 0) { + if (seqPlayer->state == 2) { + sequence_player_disable(seqPlayer); + return; + } } - goto block_8; } -block_8: - phi_s1 = arg0; - phi_s0 = 0; - if (arg0->unk0 & 0x4000000) { - arg0->unk2C = arg0->unk18 * arg0->unk28; + + if (seqPlayer->recalculateVolume) { + seqPlayer->appliedFadeVolume = seqPlayer->fadeVolume * seqPlayer->fadeVolumeScale; } - do { - temp_a0 = phi_s1->unk30; - if (((&D_803B5EF0 != temp_a0) == 1) && ((*temp_a0 >> 0x1F) == 1)) { - func_800BDE50(temp_a0, (arg0->unk0 << 5) >> 0x1F); + + // Process channels + for (i = 0; i < CHANNELS_MAX; i++) { + if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[i]) == TRUE + && seqPlayer->channels[i]->enabled == TRUE) { + sequence_channel_process_sound(seqPlayer->channels[i], seqPlayer->recalculateVolume); } - temp_s0 = phi_s0 + 4; - phi_s1 += 4; - phi_s0 = temp_s0; - } while (temp_s0 != 0x40); - arg0->unk0 = arg0->unk0 & 0xFFFB; + } + + seqPlayer->recalculateVolume = FALSE; } -#else -GLOBAL_ASM("asm/non_matchings/audio/effects/func_800BDFF8.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern f32 gPitchBendFrequencyScale; - -f32 func_800BE158(void *arg0) { - u32 temp_v0; - u32 phi_v0; - - arg0->unk4 = arg0->unk4 + arg0->unk8; - temp_v0 = arg0->unk4; - phi_v0 = temp_v0; - if (temp_v0 >= 0x80) { - phi_v0 = 0x7F; + +f32 get_portamento_freq_scale(struct Portamento *p) { + u32 v0; + f32 result; + + p->cur += p->speed; + v0 = (u32) p->cur; + + if (v0 > 127) + { + v0 = 127; } - return ((*(&gPitchBendFrequencyScale + 0x200 + (phi_v0 * 4)) - 1.0f) * arg0->unkC) + 1.0f; + + result = US_FLOAT(1.0) + p->extent * (gPitchBendFrequencyScale[v0 + 128] - US_FLOAT(1.0)); + return result; } -#else -GLOBAL_ASM("asm/non_matchings/audio/effects/func_800BE158.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s16 func_800BE22C(void *arg0) { - s32 temp_t3; - u32 temp_t9; - - temp_t9 = arg0->unk4 + arg0->unk10; - temp_t3 = ((temp_t9 >> 0xA) & 0x3F) * 2; - arg0->unk4 = temp_t9; - return *(arg0->unk8 + temp_t3) >> 8; + +s16 get_vibrato_pitch_change(struct VibratoState *vib) { + s32 index; + vib->time += (s32) vib->rate; + index = (vib->time >> 10) & 0x3F; + return vib->curve[index] >> 8; } -#else -GLOBAL_ASM("asm/non_matchings/audio/effects/func_800BE22C.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800BE22C(u16); // extern -extern f32 gPitchBendFrequencyScale; - -f32 func_800BE270(void *arg0, u16 arg1) { - f32 temp_f0; - f32 temp_f0_2; - u16 temp_v0; - u16 temp_v0_2; - u16 temp_v0_3; - u16 temp_v0_4; - u16 temp_v0_5; - void *temp_v1; - u16 phi_a1; - - temp_v0 = arg0->unk1A; - phi_a1 = arg1; - if (temp_v0 != 0) { - arg0->unk1A = temp_v0 - 1; - return 1.0f; + +f32 get_vibrato_freq_scale(struct VibratoState *vib) { + s32 pitchChange; + f32 extent; + f32 result; + + if (vib->delay != 0) { + vib->delay--; + return 1; } - temp_v0_2 = arg0->unk18; - if (temp_v0_2 != 0) { - if (temp_v0_2 == 1) { - arg0->unkC = arg0->unk0->unk12; + + if (vib->extentChangeTimer) { + if (vib->extentChangeTimer == 1) { + vib->extent = (s32) vib->seqChannel->vibratoExtentTarget; } else { - temp_f0 = arg0->unkC; - arg0->unkC = temp_f0 + ((arg0->unk0->unk12 - temp_f0) / temp_v0_2); + vib->extent += + ((s32) vib->seqChannel->vibratoExtentTarget - vib->extent) / (s32) vib->extentChangeTimer; } - arg0->unk18 = arg0->unk18 - 1; - } else { - temp_v1 = arg0->unk0; - if (arg0->unkC != temp_v1->unk12) { - temp_v0_3 = temp_v1->unk16; - arg0->unk18 = temp_v0_3; - if (temp_v0_3 == 0) { - arg0->unkC = temp_v1->unk12; - } + + vib->extentChangeTimer--; + } else if (vib->seqChannel->vibratoExtentTarget != (s32) vib->extent) { + if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) { + vib->extent = (s32) vib->seqChannel->vibratoExtentTarget; } } - temp_v0_4 = arg0->unk16; - if (temp_v0_4 != 0) { - phi_a1 = temp_v0_4; - if (temp_v0_4 == 1) { - arg0->unk10 = arg0->unk0->unk10; + + if (vib->rateChangeTimer) { + if (vib->rateChangeTimer == 1) { + vib->rate = (s32) vib->seqChannel->vibratoRateTarget; } else { - temp_f0_2 = arg0->unk10; - arg0->unk10 = temp_f0_2 + ((arg0->unk0->unk10 - temp_f0_2) / temp_v0_4); + vib->rate += ((s32) vib->seqChannel->vibratoRateTarget - vib->rate) / (s32) vib->rateChangeTimer; } - arg0->unk16 = arg0->unk16 - 1; - } else if (arg0->unk10 != arg0->unk0->unk10) { - temp_v0_5 = arg0->unk0->unk14; - arg0->unk16 = temp_v0_5; - if (temp_v0_5 == 0) { - arg0->unk10 = arg0->unk0->unk10; + + vib->rateChangeTimer--; + } else if (vib->seqChannel->vibratoRateTarget != (s32) vib->rate) { + if ((vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay) == 0) { + vib->rate = (s32) vib->seqChannel->vibratoRateTarget; } } - if (arg0->unkC == 0.0f) { + + if (vib->extent == 0) { return 1.0f; } - return ((*(&gPitchBendFrequencyScale + 0x200 + (func_800BE22C(phi_a1) * 4)) - 1.0f) * (arg0->unkC * 0.00024414062f)) + 1.0f; + + pitchChange = get_vibrato_pitch_change(vib); + extent = (f32) vib->extent / US_FLOAT(4096.0); + + result = US_FLOAT(1.0) + extent * (gPitchBendFrequencyScale[pitchChange + 128] - US_FLOAT(1.0)); + return result; } -#else -GLOBAL_ASM("asm/non_matchings/audio/effects/func_800BE270.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -f32 func_800BE158(void *, void *); // extern -f32 func_800BE270(void *, void *); // extern - -void func_800BE468(void *arg0) { - void *temp_a0; - void *temp_a1; - void *phi_a1; - - temp_a1 = arg0; - temp_a0 = arg0 + 0x7C; - phi_a1 = temp_a1; - if (arg0->unk7C != 0) { - arg0 = temp_a1; - arg0->unk38 = func_800BE158(temp_a0, temp_a1); - phi_a1 = arg0; + +void note_vibrato_update(struct Note *note) { + if (note->portamento.mode != 0) { + note->portamentoFreqScale = get_portamento_freq_scale(¬e->portamento); } - if ((phi_a1->unkA0 != 0) && (phi_a1->unk44 != -1)) { - arg0 = phi_a1; - arg0->unk3C = func_800BE270(phi_a1 + 0x8C, phi_a1); + if (note->vibratoState.active && note->parentLayer != NO_LAYER) { + note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState); } } -#else -GLOBAL_ASM("asm/non_matchings/audio/effects/func_800BE468.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern ? gWaveSamples; - -void func_800BE4D4(void *arg0) { - u16 temp_v0; - u16 temp_v0_2; - void *temp_a1; - void *temp_a1_2; - void *temp_t6; - void *temp_t9; - void *temp_v0_3; - void *temp_v1; - void *temp_v1_2; - void *phi_a1; - void *phi_v1; - - arg0->unkA0 = 1; - arg0->unk90 = 0; - arg0->unk3C = 1.0f; - arg0->unk38 = 1.0f; - temp_v1 = arg0 + 0x8C; - arg0->unk94 = *(&gWaveSamples + 8); - temp_t9 = arg0->unk44->unk4C; - arg0->unk8C = temp_t9; - temp_v0 = temp_t9->unk16; - arg0->unkA4 = temp_v0; - phi_v1 = temp_v1; - if (temp_v0 == 0) { - temp_v1_2 = arg0 + 0x8C; - temp_a1 = temp_v1_2->unk0; - temp_v1_2->unkC = temp_a1->unk12; - phi_a1 = temp_a1; - phi_v1 = temp_v1_2; + +void note_vibrato_init(struct Note *note) { + struct VibratoState *vib; + UNUSED struct SequenceChannel *seqChannel; + struct NotePlaybackState *seqPlayerState = (struct NotePlaybackState *) ¬e->priority; + + note->vibratoFreqScale = 1.0f; + note->portamentoFreqScale = 1.0f; + + vib = ¬e->vibratoState; + + vib->active = TRUE; + vib->time = 0; + + vib->curve = gWaveSamples[2]; + vib->seqChannel = note->parentLayer->seqChannel; + if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) { + vib->extent = FLOAT_CAST(vib->seqChannel->vibratoExtentTarget); } else { - temp_a1_2 = temp_v1->unk0; - temp_v1->unkC = temp_a1_2->unkE; - phi_a1 = temp_a1_2; + vib->extent = FLOAT_CAST(vib->seqChannel->vibratoExtentStart); } - temp_v0_2 = phi_a1->unk14; - phi_v1->unk16 = temp_v0_2; - if (temp_v0_2 == 0) { - phi_v1->unk10 = phi_a1->unk10; + + if ((vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay) == 0) { + vib->rate = FLOAT_CAST(vib->seqChannel->vibratoRateTarget); } else { - phi_v1->unk10 = phi_a1->unkC; + vib->rate = FLOAT_CAST(vib->seqChannel->vibratoRateStart); } - temp_v0_3 = arg0 + 0x30; - phi_v1->unk1A = phi_a1->unk18; - temp_t6 = temp_v0_3->unk14; - temp_v0_3->unk4C = temp_t6->unk8; - temp_v0_3->unk50 = temp_t6->unkC; - temp_v0_3->unk54 = temp_t6->unk10; - temp_v0_3->unk58 = temp_t6->unk14; + vib->delay = vib->seqChannel->vibratoDelay; + + seqPlayerState->portamento = seqPlayerState->parentLayer->portamento; } -#else -GLOBAL_ASM("asm/non_matchings/audio/effects/func_800BE4D4.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BE5BC(void *arg0, s32 arg1, ? arg2) { - arg0->unk0 = 0; - arg0->unk1 = 0; - arg0->unk4 = 0; - arg0->unk20 = arg1; - arg0->unk8 = 0.0f; - arg0->unk14 = 0.0f; + +void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, UNUSED s16 *volOut) { + adsr->action = 0; + adsr->state = ADSR_STATE_DISABLED; + adsr->delay = 0; + adsr->envelope = envelope; + adsr->sustain = 0.0f; + adsr->current = 0.0f; } -#else -GLOBAL_ASM("asm/non_matchings/audio/effects/func_800BE5BC.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit bd0364fa19633bd6201f8007e2d0a7ed87825909 -extern ? gAudioBufferParameters; - -f32 func_800BE5E0(void *arg0) { - f32 temp_f0; - f32 temp_f0_2; - f32 temp_f2; - f32 temp_f6; - s16 temp_a2; - s16 temp_v1_3; - u8 temp_v0; - u8 temp_v1; - void *temp_v1_2; - s16 phi_a2; - - temp_v1 = arg0->unk1; - temp_v0 = arg0->unk0; - switch (temp_v1) { - case 0: - return 0.0f; - case 1: - if ((temp_v0 & 0x40) != 0) { - arg0->unk1 = 5; - } else { - case 2: - arg0->unk2 = 0; - arg0->unk1 = 3; - case 3: -loop_6: - temp_v1_2 = arg0->unk20 + (arg0->unk2 * 4); - arg0->unk4 = temp_v1_2->unk0; - temp_a2 = arg0->unk4; - if (temp_a2 != -3) { - if (temp_a2 != -2) { - if (temp_a2 != -1) { - if (temp_a2 == 0) { - arg0->unk1 = 0; - } else { - if (temp_a2 >= 4) { - arg0->unk4 = ((temp_a2 * gAudioBufferParameters.unkC) / gAudioBufferParameters.unk0) / 4; - } - phi_a2 = arg0->unk4; - if (arg0->unk4 == 0) { - arg0->unk4 = 1; - phi_a2 = arg0->unk4; - } - temp_v1_3 = arg0->unk2; - arg0->unk1 = 4; - temp_f6 = (arg0->unk20 + (temp_v1_3 * 4))->unk2; - arg0->unk2 = temp_v1_3 + 1; - arg0->unk18 = temp_f6 / 32767.0f; - temp_f0 = arg0->unk18; - arg0->unk18 = temp_f0 * temp_f0; - arg0->unkC = (arg0->unk18 - arg0->unk14) / phi_a2; - } - } else { - arg0->unk1 = 5; + +f32 adsr_update(struct AdsrState *adsr) { + u8 action = adsr->action; + u8 state = adsr->state; + switch (state) { + case ADSR_STATE_DISABLED: + return 0; + + case ADSR_STATE_INITIAL: { + if (action & ADSR_ACTION_HANG) { + adsr->state = ADSR_STATE_HANG; + break; + } + // fallthrough + } + + case ADSR_STATE_START_LOOP: + adsr->envIndex = 0; + adsr->state = ADSR_STATE_LOOP; + // fallthrough + +restart: + case ADSR_STATE_LOOP: + adsr->delay = BSWAP16(adsr->envelope[adsr->envIndex].delay); + switch (adsr->delay) { + case ADSR_DISABLE: + adsr->state = ADSR_STATE_DISABLED; + break; + case ADSR_HANG: + adsr->state = ADSR_STATE_HANG; + break; + case ADSR_GOTO: + adsr->envIndex = BSWAP16(adsr->envelope[adsr->envIndex].arg); + goto restart; + case ADSR_RESTART: + adsr->state = ADSR_STATE_INITIAL; + break; + + default: + if (adsr->delay >= 4) { + adsr->delay = adsr->delay * gAudioBufferParameters.updatesPerFrame + / gAudioBufferParameters.presetUnk4 + / 4; } - } else { - arg0->unk2 = temp_v1_2->unk2; - goto loop_6; - } - } else { - arg0->unk1 = 1; + if (adsr->delay == 0) { + adsr->delay = 1; + } + adsr->target = (f32) BSWAP16(adsr->envelope[adsr->envIndex].arg) / 32767.0f; + adsr->target = adsr->target * adsr->target; + adsr->velocity = (adsr->target - adsr->current) / adsr->delay; + adsr->state = ADSR_STATE_FADE; + adsr->envIndex++; + break; + } + if (adsr->state != ADSR_STATE_FADE) { + break; + } + // fallthrough + + case ADSR_STATE_FADE: + adsr->current += adsr->velocity; + if (--adsr->delay <= 0) { + adsr->state = ADSR_STATE_LOOP; } - if (arg0->unk1 == 4) { - case 4: - arg0->unk4 = arg0->unk4 - 1; - arg0->unk14 = arg0->unk14 + arg0->unkC; - if (arg0->unk4 <= 0) { - arg0->unk1 = 3; + // fallthrough + + case ADSR_STATE_HANG: + break; + + case ADSR_STATE_DECAY: + case ADSR_STATE_RELEASE: { + adsr->current -= adsr->fadeOutVel; + if (adsr->sustain != 0.0f && state == ADSR_STATE_DECAY) { + if (adsr->current < adsr->sustain) { + adsr->current = adsr->sustain; + adsr->delay = 128; + adsr->state = ADSR_STATE_SUSTAIN; } + break; } - } - default: -block_30: - if ((temp_v0 & 0x20) != 0) { - arg0->unk1 = 6; - arg0->unk0 = temp_v0 & 0xFFDF; - } - if ((temp_v0 & 0x10) != 0) { - arg0->unk1 = 7; - arg0->unk0 = temp_v0 & 0xFFEF; - } - temp_f2 = arg0->unk14; - if (temp_f2 < 0.0f) { - return 0.0f; - } - if (temp_f2 > 1.0f) { - return 1.0f; - } - return temp_f2; - case 6: - case 7: - temp_f0_2 = arg0->unk8; - arg0->unk14 = arg0->unk14 - arg0->unk10; - if ((temp_f0_2 != 0.0f) && (temp_v1 == 6)) { - if (arg0->unk14 < temp_f0_2) { - arg0->unk14 = temp_f0_2; - arg0->unk4 = 0x80; - arg0->unk1 = 8; + + if (adsr->current < 0.00001f) { + adsr->current = 0.0f; + adsr->state = ADSR_STATE_DISABLED; } - } else if (arg0->unk14 < 0.00001f) { - arg0->unk14 = 0.0f; - arg0->unk1 = 0; + break; } - goto block_30; - case 8: - arg0->unk4 = arg0->unk4 - 1; - if (arg0->unk4 == 0) { - arg0->unk1 = 7; - } - goto block_30; + + case ADSR_STATE_SUSTAIN: + adsr->delay -= 1; + if (adsr->delay == 0) { + adsr->state = ADSR_STATE_RELEASE; + } + break; + } + + if ((action & ADSR_ACTION_DECAY)) { + adsr->state = ADSR_STATE_DECAY; + adsr->action = action & ~ADSR_ACTION_DECAY; + } + + if ((action & ADSR_ACTION_RELEASE)) { + adsr->state = ADSR_STATE_RELEASE; + adsr->action = action & ~ADSR_ACTION_RELEASE; + } + + if (adsr->current < 0.0f) { + // Don't actually know where this goes, but we need that string + // somewhere in the .data section for this file + eu_stubbed_printf_0("Env-Clear 0\n"); + return 0.0f; + } + if (adsr->current > 1.0f) { + eu_stubbed_printf_1("Audio:Envp: overflow %f\n", adsr->current); + return 1.0f; } + return adsr->current; } -#else -GLOBAL_ASM("asm/non_matchings/audio/effects/func_800BE5E0.s") -#endif diff --git a/src/audio/effects.h b/src/audio/effects.h index 796b078b8..f7cc4957d 100644 --- a/src/audio/effects.h +++ b/src/audio/effects.h @@ -1,6 +1,8 @@ #ifndef AUDIO_EFFECTS_H #define AUDIO_EFFECTS_H +#include "audio/internal.h" + #ifdef TARGET_N64 #define IS_BIG_ENDIAN 1 #endif @@ -32,4 +34,14 @@ #define BSWAP16(x) (((x) & 0xff) << 8 | (((x) >> 8) & 0xff)) #endif +void sequence_channel_process_sound(struct SequenceChannel *seqChannel, s32 recalculateVolume); +void sequence_player_process_sound(struct SequencePlayer *seqPlayer); +f32 get_portamento_freq_scale(struct Portamento *p); +s16 get_vibrato_pitch_change(struct VibratoState *vib); +f32 get_vibrato_freq_scale(struct VibratoState *vib); +void note_vibrato_update(struct Note *note); +void note_vibrato_init(struct Note *note); +void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, s16 *volOut); +f32 adsr_update(struct AdsrState *adsr); + #endif /* AUDIO_EFFECTS_H */ diff --git a/src/audio/external.c b/src/audio/external.c index 52dad1c23..5bfc5e105 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -84,7 +84,7 @@ GLOBAL_ASM("asm/non_matchings/audio/external/func_800C1480.s") extern s8 D_8018EF10; extern ? D_80191420; extern s32 D_803B17D0; -extern ? D_803B5EF0; +extern ? gSequenceChannelNone; s8 func_800C15D0(s32 arg0, s32 arg1, s32 arg2) { ? sp-10; @@ -112,7 +112,7 @@ s8 func_800C15D0(s32 arg0, s32 arg1, s32 arg2) { } } temp_a0 = *(&D_803B17D0 + ((arg2 & 0xFF) * 4)); - if (&D_803B5EF0 != temp_a0) { + if (&gSequenceChannelNone != temp_a0) { phi_v1 = temp_a0->unk5E; } phi_v1_2 = phi_v1; @@ -555,7 +555,7 @@ GLOBAL_ASM("asm/non_matchings/audio/external/func_800C21E8.s") void func_8001AAAC(s16, s16, s16); // extern void func_800CBBE8(s32, ?, s32, s32); // extern extern ? D_8018FC10; -extern u32 D_803B1510; +extern u32 gSequencePlayers; void func_800C2274(s32 arg0) { s16 sp46; @@ -577,7 +577,7 @@ void func_800C2274(s32 arg0) { temp_a3 = arg0 & 0xFF; phi_a2 = 0xF; - if ((*(&D_803B1510 + (temp_a3 * 0x148)) >> 0x1F) != 0) { + if ((*(&gSequencePlayers + (temp_a3 * 0x148)) >> 0x1F) != 0) { temp_v0 = D_800DC530; if (temp_v0 != 0) { if (temp_v0 != 1) { @@ -593,7 +593,7 @@ void func_800C2274(s32 arg0) { phi_a2 = 0xE; } } - temp_v0_2 = (&D_803B1510 + (temp_a3 * 0x148) + (phi_a2 * 4))->unk30; + temp_v0_2 = (&gSequencePlayers + (temp_a3 * 0x148) + (phi_a2 * 4))->unk30; temp_s0 = temp_v0_2->unk58; if (temp_s0 != 0xFF) { sp46 = temp_v0_2->unk59 & 3; @@ -1295,7 +1295,7 @@ GLOBAL_ASM("asm/non_matchings/audio/external/func_800C3478.s") #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 extern ? D_80193318; -extern u32 D_803B1510; +extern u32 gSequencePlayers; u16 func_800C3508(s32 arg0) { ? sp-10; @@ -1303,7 +1303,7 @@ u16 func_800C3508(s32 arg0) { temp_t6 = arg0 & 0xFF; sp-10.unk10 = arg0; - if ((*(&D_803B1510 + (temp_t6 * 0x148)) >> 0x1F) == 0) { + if ((*(&gSequencePlayers + (temp_t6 * 0x148)) >> 0x1F) == 0) { return 0xFFFF; } return *(&D_80193318 + (temp_t6 * 0x24C)); @@ -1422,7 +1422,7 @@ void func_800C36C4(s32, ?, ?, ?); /* extern */ void func_800CBB88(s32, f32, s32); /* extern */ void func_800CBBB8(s32, s32); /* extern */ extern ? D_801930D0; -extern u32 D_803B1510; +extern u32 gSequencePlayers; void func_800C3724(void) { f32 temp_f0; @@ -1534,7 +1534,7 @@ void func_800C3724(void) { if (temp_a3 == 0) { phi_t0 = (temp_a3 + 1) & 0xFF; } - temp_a1_2 = (phi_s5 * 0x148) + &D_803B1510; + temp_a1_2 = (phi_s5 * 0x148) + &gSequencePlayers; if ((temp_a1_2->unk0 >> 0x1F) != 0) { temp_t9_2 = ((temp_a1 & 0xF000) >> 0xC) & 0xFF; temp_lo = temp_a1_2->unk8 / 48; @@ -1655,7 +1655,7 @@ void func_800C3724(void) { temp_s3->unk40 = temp_v1_6 - 1; } else { phi_s2_2 = 0; - if ((*(&D_803B1510 + (phi_s5 * 0x148)) >> 0x1F) == 0) { + if ((*(&gSequencePlayers + (phi_s5 * 0x148)) >> 0x1F) == 0) { phi_v1 = temp_v0_6; if (temp_v0_6 > 0) { do { @@ -2995,13 +2995,13 @@ void func_800C4FE4(s32); // extern void func_800C5968(s32); // extern extern s8 D_80192C38; extern s32 D_803B17D0; -extern ? D_803B5EF0; +extern ? gSequenceChannelNone; void func_800C59C4(void) { s32 temp_t8; s32 phi_s0; - if (&D_803B5EF0 != D_803B17D0) { + if (&gSequenceChannelNone != D_803B17D0) { D_80192C38 = 0; phi_s0 = 0; do { diff --git a/src/audio/external.h b/src/audio/external.h index 0cabd6841..34569e33b 100644 --- a/src/audio/external.h +++ b/src/audio/external.h @@ -3,6 +3,19 @@ #include "common_structs.h" +// Sequence arguments, passed to seq_player_play_sequence. seqId may be bit-OR'ed with +// SEQ_VARIATION; this will load the same sequence, but set a variation +// bit which may be read by the sequence script. +#define SEQUENCE_ARGS(priority, seqId) ((priority << 8) | seqId) + +#define SOUND_MODE_STEREO 0 +#define SOUND_MODE_MONO 3 +#define SOUND_MODE_HEADSET 1 + +#define SEQ_PLAYER_LEVEL 0 // Level background music +#define SEQ_PLAYER_ENV 1 // Misc music like the puzzle jingle +#define SEQ_PLAYER_SFX 2 // Sound effects + void play_sound2(s32); void func_800C8EAC(u16); void func_800C8EF8(); @@ -26,4 +39,7 @@ extern s8 D_800EA0F4; extern s8 D_800EA108; extern s16 D_800EA174; +// Based on SM64, this should be part of data.c's BSS section. Somehow. +extern s32 gAudioErrorFlags; + #endif diff --git a/src/audio/heap.c b/src/audio/heap.c index e64902a89..dcf11b483 100644 --- a/src/audio/heap.c +++ b/src/audio/heap.c @@ -1,14 +1,17 @@ #include <ultra64.h> #include <macros.h> -#include "heap.h" +#include "audio/heap.h" +#include "audio/load.h" +#include "audio/playback.h" +#include "audio/seqplayer.h" extern struct SoundAllocPool gNotesAndBuffersPool; #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 extern u8 D_803B0380; -extern u8 D_803B03C0; -extern ? D_803B0400; +extern u8 gBankLoadStatus; +extern ? gSeqLoadStatus; extern u8 D_803B0500; void func_800B8DE0(void) { @@ -19,14 +22,14 @@ void func_800B8DE0(void) { u8 *phi_v1_2; ? *phi_v1_3; - phi_v1 = &D_803B03C0; + phi_v1 = &gBankLoadStatus; do { if (*phi_v1 != 5) { *phi_v1 = 0; } temp_v1 = phi_v1 + 1; phi_v1 = temp_v1; - } while (temp_v1 < &D_803B0400); + } while (temp_v1 < &gSeqLoadStatus); phi_v1_2 = &D_803B0380; do { if (*phi_v1_2 != 5) { @@ -34,8 +37,8 @@ void func_800B8DE0(void) { } temp_v1_2 = phi_v1_2 + 1; phi_v1_2 = temp_v1_2; - } while (temp_v1_2 < &D_803B03C0); - phi_v1_3 = &D_803B0400; + } while (temp_v1_2 < &gBankLoadStatus); + phi_v1_3 = &gSeqLoadStatus; do { if (phi_v1_3->unk0 != 5) { phi_v1_3->unk0 = 0; @@ -57,169 +60,91 @@ void func_800B8DE0(void) { GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B8DE0.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BCB48(void *); // extern -void func_800BD6F4(void *); // extern -void func_800BF004(? *, void *); // extern -extern s32 D_803B1508; -extern ? D_803B5FC8; -extern s32 gMaxSimultaneousNotes; +void discard_bank(s32 bankId) { + s32 i; -void func_800B8EA8(s32 arg0) { - s32 temp_s2; - s32 temp_v0; - u8 *temp_v0_2; - u8 *temp_v0_3; - void *temp_s0; - s32 phi_s1; - s32 phi_s2; - s32 phi_v0; + for (i = 0; i < gMaxSimultaneousNotes; i++) { + struct Note *note = &gNotes[i]; - temp_v0 = gMaxSimultaneousNotes; - phi_s2 = 0; - phi_v0 = temp_v0; - if (temp_v0 > 0) { - phi_s1 = 0; - do { - temp_s0 = phi_s1 + D_803B1508; - if (arg0 == temp_s0->unkB2) { - if (temp_s0->unk30 >= 2) { - temp_v0_2 = temp_s0->unk44; - *temp_v0_2 = *temp_v0_2 & 0xFF7F; - temp_v0_3 = temp_s0->unk44; - *temp_v0_3 = *temp_v0_3 | 0x40; - } - func_800BCB48(temp_s0); - func_800BD6F4(temp_s0); - func_800BF004(&D_803B5FC8, temp_s0); - phi_v0 = gMaxSimultaneousNotes; + if (note->noteSubEu.bankId == bankId) { + // (These prints are unclear. Arguments are picked semi-randomly.) + eu_stubbed_printf_1("Warning:Kill Note %x \n", i); + if (note->priority >= NOTE_PRIORITY_MIN) { + eu_stubbed_printf_3("Kill Voice %d (ID %d) %d\n", note->waveId, + bankId, note->priority); + eu_stubbed_printf_0("Warning: Running Sequence's data disappear!\n"); + note->parentLayer->enabled = FALSE; // is 0x48, should be 0x44 + note->parentLayer->finished = TRUE; } - temp_s2 = phi_s2 + 1; - phi_s1 += 0xC0; - phi_s2 = temp_s2; - } while (temp_s2 < phi_v0); + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(&gNoteFreeLists.disabled, ¬e->listItem); + } } } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B8EA8.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BEF2C(? *); // extern -extern u32 D_803B1510; -extern ? D_803B1A30; -void func_800B8F8C(s32 arg0) { - ? *temp_s0; - ? *phi_s0; +void discard_sequence(s32 seqId) { + s32 i; - phi_s0 = &D_803B1510; - do { - if (((phi_s0->unk0 >> 0x1F) != 0) && (arg0 == phi_s0->unk4)) { - func_800BEF2C(phi_s0); + for (i = 0; i < SEQUENCE_PLAYERS; i++) { + if (gSequencePlayers[i].enabled && gSequencePlayers[i].seqId == seqId) { + sequence_player_disable(&gSequencePlayers[i]); } - temp_s0 = phi_s0 + 0x148; - phi_s0 = temp_s0; - } while (temp_s0 != &D_803B1A30); + } } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B8F8C.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -u32 soundAlloc(void *arg0, s32 arg1) { - s32 temp_t6; - s8 *temp_a1; - u32 temp_a2; - u32 temp_t1; - s8 *phi_a1; +void *soundAlloc(struct SoundAllocPool *pool, u32 size) { + u8 *start; + u8 *pos; + u32 alignedSize = ALIGN16(size); - temp_a2 = arg0->unk4; - temp_t6 = (arg1 + 0xF) & ~0xF; - if ((arg0->unk0 + arg0->unk8) >= (temp_a2 + temp_t6)) { - temp_t1 = temp_a2 + temp_t6; - arg0->unk4 = temp_t1; - phi_a1 = temp_a2; - if (temp_a2 < temp_t1) { - do { - *phi_a1 = 0; - temp_a1 = phi_a1 + 1; - phi_a1 = temp_a1; - } while (temp_a1 < arg0->unk4); + start = pool->cur; + if (start + alignedSize <= pool->start + pool->size) { + pool->cur += alignedSize; + for (pos = start; pos < pool->cur; pos++) { + *pos = 0; } - arg0->unkC = arg0->unkC + 1; - return temp_a2; + } else { + eu_stubbed_printf_1("Heap OverFlow : Not Allocate %d!\n", size); + return NULL; } - return 0; + pool->numAllocatedEntries++; + return start; } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/soundAlloc.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800B907C(void *arg0, s32 arg1, s32 arg2) { - s32 temp_t6; - - temp_t6 = (arg1 + 0xF) & ~0xF; - arg0->unk0 = temp_t6; - arg0->unk4 = temp_t6; - arg0->unk8 = arg2; - arg0->unkC = 0; +void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size) { + pool->cur = pool->start = (u8 *) ALIGN16((uintptr_t) memAddr); + pool->size = size; + pool->numAllocatedEntries = 0; } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B907C.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800B909C(void *arg0) { - arg0->unk10 = 0; - arg0->unk0 = 0; - arg0->unk8 = arg0->unk4; +void persistent_pool_clear(struct PersistentPool *persistent) { + persistent->pool.numAllocatedEntries = 0; + persistent->pool.cur = persistent->pool.start; + persistent->numEntries = 0; } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B909C.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800B90B0(void *arg0) { - s32 temp_v0; - temp_v0 = arg0->unk4; - arg0->unk10 = 0; - arg0->unk0 = 0; - arg0->unk20 = temp_v0 + arg0->unkC; - arg0->unk1E = -1; - arg0->unk2A = -1; - arg0->unk8 = temp_v0; - arg0->unk14 = temp_v0; +void temporary_pool_clear(struct TemporaryPool *temporary) { + temporary->pool.numAllocatedEntries = 0; + temporary->pool.cur = temporary->pool.start; + temporary->nextSide = 0; + temporary->entries[0].ptr = temporary->pool.start; + temporary->entries[1].ptr = temporary->pool.start + temporary->pool.size; + temporary->entries[0].id = -1; // should be at 1e not 1c + temporary->entries[1].id = -1; } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B90B0.s") -#endif -struct struct_800B90E0 { - s32 unk0; - s32 unk4; - s32 unk8; - s32 unkC; -}; -UNUSED void func_800B90E0(struct struct_800B90E0 *arg0) { - arg0->unkC = 0; - arg0->unk4 = arg0->unk0; +void func_800B90E0(struct SoundAllocPool *pool) { + pool->numAllocatedEntries = 0; + pool->cur = pool->start; } #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800B907C(? *, ? *, s32, s32); // extern +void sound_alloc_pool_init(? *, ? *, s32, s32); // extern extern s32 D_800EA5D0; -extern ? D_803AFBC8; -extern ? D_803AFBD8; +extern ? gAudioSessionPool; +extern ? gAudioInitPool; extern ? D_803B71B0; void func_800B90F0(s32 arg0) { @@ -227,8 +152,8 @@ void func_800B90F0(s32 arg0) { temp_a2 = arg0; arg0 = temp_a2; - func_800B907C(&D_803AFBD8, &D_803B71B0, temp_a2); - func_800B907C(&D_803AFBC8, arg0 + &D_803B71B0, D_800EA5D0 - arg0, arg0); + sound_alloc_pool_init(&gAudioInitPool, &D_803B71B0, temp_a2); + sound_alloc_pool_init(&gAudioSessionPool, arg0 + &D_803B71B0, D_800EA5D0 - arg0, arg0); } #else GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B90F0.s") @@ -237,379 +162,269 @@ GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B90F0.s") #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 s32 soundAlloc(? *, s32); // extern -void func_800B907C(? *, s32, s32); // extern -extern ? D_803AFBC8; +void sound_alloc_pool_init(? *, s32, s32); // extern +extern ? gAudioSessionPool; extern ? gNotesAndBuffersPool; -extern ? D_803AFC18; +extern ? gSeqAndBankPool; void func_800B914C(void *arg0) { - D_803AFBC8.unk4 = D_803AFBC8.unk0; - func_800B907C(&gNotesAndBuffersPool, soundAlloc(&D_803AFBC8, arg0->unk0), arg0->unk0); - func_800B907C(&D_803AFC18, soundAlloc(&D_803AFBC8, arg0->unkC), arg0->unkC); + gAudioSessionPool.unk4 = gAudioSessionPool.unk0; + sound_alloc_pool_init(&gNotesAndBuffersPool, soundAlloc(&gAudioSessionPool, arg0->unk0), arg0->unk0); + sound_alloc_pool_init(&gSeqAndBankPool, soundAlloc(&gAudioSessionPool, arg0->unkC), arg0->unkC); } #else GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B914C.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 soundAlloc(? *, s32); // extern -void func_800B907C(? *, s32, s32); // extern -extern ? D_803AFC18; -extern ? D_803AFC28; -extern ? D_803AFC38; - -void func_800B91C8(void *arg0) { - D_803AFC18.unk4 = D_803AFC18.unk0; - func_800B907C(&D_803AFC28, soundAlloc(&D_803AFC18, arg0->unk0), arg0->unk0); - func_800B907C(&D_803AFC38, soundAlloc(&D_803AFC18, arg0->unk4), arg0->unk4); +void seq_and_bank_pool_init(struct PoolSplit2 *a) { + gSeqAndBankPool.cur = gSeqAndBankPool.start; + sound_alloc_pool_init(&gPersistentCommonPool, soundAlloc(&gSeqAndBankPool, a->wantPersistent), a->wantPersistent); + sound_alloc_pool_init(&gTemporaryCommonPool, soundAlloc(&gSeqAndBankPool, a->wantTemporary), a->wantTemporary); } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B91C8.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 soundAlloc(? *, s32); // extern -void func_800B907C(? *, s32, s32); // extern -void func_800B909C(? *); // extern -extern ? D_803AFC28; -extern u32 D_803AFC48; -extern ? D_803AFC4C; -extern u32 D_803AFE18; -extern ? D_803AFE1C; -extern u32 D_803AFFE8; -extern ? D_803AFFEC; - -void func_800B9244(void *arg0) { - D_803AFC28.unk4 = D_803AFC28.unk0; - func_800B907C(&D_803AFC4C, soundAlloc(&D_803AFC28, arg0->unk0), arg0->unk0); - func_800B907C(&D_803AFE1C, soundAlloc(&D_803AFC28, arg0->unk4), arg0->unk4); - func_800B907C(&D_803AFFEC, soundAlloc(&D_803AFC28, arg0->unk8), arg0->unk8); - func_800B909C(&D_803AFC48); - func_800B909C(&D_803AFE18); - func_800B909C(&D_803AFFE8); +void persistent_pools_init(struct PoolSplit *a) { + gPersistentCommonPool.cur = gPersistentCommonPool.start; + sound_alloc_pool_init(&gSeqLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gBankLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantBank), a->wantBank); + sound_alloc_pool_init(&gUnusedLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantUnused), a->wantUnused); + persistent_pool_clear(&gSeqLoadedPool.persistent); + persistent_pool_clear(&gBankLoadedPool.persistent); + persistent_pool_clear(&gUnusedLoadedPool.persistent); } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B9244.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 soundAlloc(? *, s32); // extern -void func_800B907C(? *, s32, s32); // extern -void func_800B90B0(? *); // extern -extern ? D_803AFC38; -extern ? D_803AFDDC; -extern ? D_803AFDE0; -extern ? D_803AFFAC; -extern ? D_803AFFB0; -extern ? D_803B017C; -extern ? D_803B0180; - -void func_800B9300(void *arg0) { - D_803AFC38.unk4 = D_803AFC38.unk0; - func_800B907C(&D_803AFDE0, soundAlloc(&D_803AFC38, arg0->unk0), arg0->unk0); - func_800B907C(&D_803AFFB0, soundAlloc(&D_803AFC38, arg0->unk4), arg0->unk4); - func_800B907C(&D_803B0180, soundAlloc(&D_803AFC38, arg0->unk8), arg0->unk8); - func_800B90B0(&D_803AFDDC); - func_800B90B0(&D_803AFFAC); - func_800B90B0(&D_803B017C); +void temporary_pools_init(struct PoolSplit *a) { + gTemporaryCommonPool.cur = gTemporaryCommonPool.start; + sound_alloc_pool_init(&gSeqLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gBankLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantBank), a->wantBank); + sound_alloc_pool_init(&gUnusedLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantUnused), a->wantUnused); + temporary_pool_clear(&gSeqLoadedPool.temporary); + temporary_pool_clear(&gBankLoadedPool.temporary); + temporary_pool_clear(&gUnusedLoadedPool.temporary); } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B9300.s") -#endif #ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800B8EA8(s16, s32, s16, s32 *); // extern -void func_800B8F8C(s16, s32); // extern -s32 soundAlloc(s32, s32); // extern -extern u32 D_803AFC48; -extern u32 D_803AFE18; -extern u32 D_803AFFE8; -extern u8 D_803B0380; -extern u8 D_803B03C0; -extern ? D_803B0400; -extern void *D_803B1508; -extern u32 D_803B1510; -extern ? D_803B1A30; -extern s32 gMaxSimultaneousNotes; +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +? discard_bank(s16, s32, s16, struct TemporaryPool *); /* extern */ +? discard_sequence(s16, s32); /* extern */ +extern ? D_803B0380; +extern ? gBankLoadStatus; +extern ? gSeqLoadStatus; +extern void *gNotes; +extern ? gSequencePlayers; +extern ? gSequenceChannels; -u32 func_800B93BC(s32 *arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { +void *func_800B93BC(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id) { ? *sp34; u8 sp33; - s32 *sp28; - void *sp24; + struct TemporaryPool *sp28; + struct SoundAllocPool *sp24; s32 sp20; - ? *temp_v0_4; - ? *temp_v0_5; + ? *var_v0_4; + ? *var_v0_5; s16 temp_a0; s16 temp_a2; - s16 temp_v1_5; - s32 *temp_a3; - s32 temp_a0_2; + s16 temp_v1_2; s32 temp_a1; s32 temp_a1_2; s32 temp_a1_3; s32 temp_a1_4; - s32 temp_v0_6; - s32 temp_v0_9; - s32 temp_v1; - s32 temp_v1_2; - s32 temp_v1_3; - s32 temp_v1_4; - s32 temp_v1_8; - u32 temp_v0; - u32 temp_v0_7; - u32 temp_v0_8; + s32 var_a3; + s32 var_v1_2; + s32 var_v1_3; + s32 var_v1_4; + s32 var_v1_5; + struct SoundAllocPool *temp_v1_3; + struct SoundAllocPool *temp_v1_4; + struct TemporaryPool *var_a3_2; + u32 temp_a0_2; + u32 temp_v1; + u32 var_v0_3; + u8 *temp_v0; u8 *temp_v0_2; u8 *temp_v0_3; - void *temp_v1_6; - void *temp_v1_7; - s32 phi_a3; - u8 phi_t1; - void *phi_v0; - s32 phi_v1; - s32 phi_v1_2; - u8 phi_t2; - void *phi_v0_2; - s32 phi_v1_3; - s32 phi_v1_4; - u8 phi_t1_2; - u8 phi_t2_2; - ? *phi_v0_3; - ? *phi_v0_4; - ? *phi_v0_5; - ? *phi_v0_6; - void *phi_v0_7; - s32 phi_v1_5; - s32 phi_v1_6; - void *phi_v0_8; - s32 phi_v1_7; - s32 phi_v1_8; - s32 phi_v0_9; - s16 phi_a2; - s16 phi_ra; - s32 phi_t4; - s32 *phi_a3_2; - void *phi_v1_9; - s32 *phi_a3_3; - void *phi_v1_10; - s32 *phi_a3_4; - u32 phi_v1_11; - s16 phi_a2_2; - s32 *phi_a3_5; - u32 phi_v0_10; + u8 *temp_v0_4; + u8 *var_v0_8; + u8 *var_v1; + u8 var_t1; + u8 var_t2; + void *var_v0; + void *var_v0_2; + void *var_v0_6; + void *var_v0_7; - phi_a3 = arg3; - phi_t4 = 1; + var_a3 = arg3; loop_1: - phi_ra = arg4; - phi_t4 = 1; - if (phi_a3 == 0) { - temp_a3 = arg0 + 0x194; - if (arg0 == &D_803AFC48) { - sp34 = &D_803B0400; + if (var_a3 == 0) { + var_a3_2 = &arg0->temporary; + if (arg0 == &gSeqLoadedPool) { + sp34 = &gSeqLoadStatus; sp33 = 0; - } else if (arg0 == &D_803AFE18) { + } else if (arg0 == &gBankLoadedPool) { sp33 = 1; - sp34 = &D_803B03C0; - } else if (arg0 == &D_803AFFE8) { + sp34 = &gBankLoadStatus; + } else if (arg0 == &gUnusedLoadedPool) { sp33 = 2; sp34 = &D_803B0380; } - temp_a2 = temp_a3->unk1E; - phi_a2 = temp_a2; - phi_a2_2 = temp_a2; - phi_a2 = temp_a2; + temp_a2 = var_a3_2->entries[0].id; if (temp_a2 == -1) { - phi_t1 = 0; + var_t1 = 0; } else { - phi_t1 = *(temp_a2 + sp34); + var_t1 = *(temp_a2 + sp34); } - temp_a0 = temp_a3->unk2A; - phi_t1_2 = phi_t1; - phi_t1_2 = phi_t1; + temp_a0 = var_a3_2->entries[1].id; if (temp_a0 == -1) { - phi_t2 = 0; + var_t2 = 0; } else { - phi_t2 = *(temp_a0 + sp34); + var_t2 = *(temp_a0 + sp34); } - sp20 = sp33; - phi_t2_2 = phi_t2; + sp20 = (s32) sp33; if (sp33 == 1) { - if (phi_t1 == 4) { + if (var_t1 == 4) { temp_a1 = gMaxSimultaneousNotes; - phi_v1 = 0; - phi_v1_2 = 0; + var_v1_2 = 0; if (temp_a1 > 0) { - phi_v0 = D_803B1508; + var_v0 = gNotes; loop_18: - phi_v1_2 = phi_v1; - if ((phi_v0->unkB2 != temp_a2) || ((phi_v0->unkB0 >> 0x1F) == 0)) { - temp_v1 = phi_v1 + 1; - phi_v0 += 0xC0; - phi_v1 = temp_v1; - phi_v1_2 = temp_v1; - if (temp_v1 < temp_a1) { + if ((var_v0->unkB2 != temp_a2) || (((u32) var_v0->unkB0 >> 0x1F) == 0)) { + var_v1_2 += 1; + var_v0 += 0xC0; + if (var_v1_2 < temp_a1) { goto loop_18; } } } - temp_v0_2 = &D_803B03C0 + temp_a2; - if (phi_v1_2 == temp_a1) { - phi_t1_2 = 3; - if (*temp_v0_2 != 5) { - *temp_v0_2 = 3; + temp_v0 = &gBankLoadStatus + temp_a2; + if (var_v1_2 == temp_a1) { + var_t1 = 3; + if (*temp_v0 != 5) { + *temp_v0 = 3; } } } - if (phi_t2 == 4) { + if (var_t2 == 4) { temp_a1_2 = gMaxSimultaneousNotes; - phi_v1_3 = 0; - phi_v1_4 = 0; + var_v1_3 = 0; if (temp_a1_2 > 0) { - phi_v0_2 = D_803B1508; + var_v0_2 = gNotes; loop_27: - phi_v1_4 = phi_v1_3; - if ((phi_v0_2->unkB2 != temp_a3->unk2A) || ((phi_v0_2->unkB0 >> 0x1F) == 0)) { - temp_v1_2 = phi_v1_3 + 1; - phi_v0_2 += 0xC0; - phi_v1_3 = temp_v1_2; - phi_v1_4 = temp_v1_2; - if (temp_v1_2 < temp_a1_2) { + if ((var_v0_2->unkB2 != var_a3_2->entries[1].id) || (((u32) var_v0_2->unkB0 >> 0x1F) == 0)) { + var_v1_3 += 1; + var_v0_2 += 0xC0; + if (var_v1_3 < temp_a1_2) { goto loop_27; } } } - if (phi_v1_4 == temp_a1_2) { - temp_v0_3 = &D_803B03C0 + temp_a3->unk2A; - phi_t2_2 = 3; - if (*temp_v0_3 != 5) { - *temp_v0_3 = 3; + if (var_v1_3 == temp_a1_2) { + temp_v0_2 = &gBankLoadStatus + var_a3_2->entries[1].id; + var_t2 = 3; + if (*temp_v0_2 != 5) { + *temp_v0_2 = 3; } } } } - if (phi_t1_2 == 0) { - temp_a3->unk0 = 0; - phi_v0_9 = 0; + if (var_t1 == 0) { + var_a3_2->nextSide = 0; + var_v0_3 = 0; goto block_84; } - if (phi_t2_2 == 0) { - temp_a3->unk0 = 1; - phi_v0_9 = 1; + if (var_t2 == 0) { + var_v0_3 = 1; + var_a3_2->nextSide = 1; goto block_84; } - if ((phi_t1_2 == 3) && (phi_t2_2 == 3)) { - phi_v0_9 = temp_a3->unk0; + if ((var_t1 == 3) && (var_t2 == 3)) { + var_v0_3 = var_a3_2->nextSide; goto block_84; } - if (phi_t1_2 == 3) { - temp_a3->unk0 = 0; - phi_v0_9 = 0; + if (var_t1 == 3) { + var_a3_2->nextSide = 0; + var_v0_3 = 0; goto block_84; } - if (phi_t2_2 == 3) { - temp_a3->unk0 = 1; - phi_v0_9 = 1; + if (var_t2 == 3) { + var_v0_3 = 1; + var_a3_2->nextSide = 1; goto block_84; } if (sp20 == 0) { - if (phi_t1_2 == 2) { - phi_v0_3 = &D_803B1510; + if (var_t1 == 2) { + var_v0_4 = &gSequencePlayers; loop_47: - phi_v0_4 = phi_v0_3; - if (((phi_v0_3->unk0 >> 0x1F) == 0) || (phi_v0_3->unk4 != temp_a3->unk1E)) { - temp_v0_4 = phi_v0_3 + 0x148; - phi_v0_3 = temp_v0_4; - phi_v0_4 = temp_v0_4; - if (temp_v0_4 != &D_803B1A30) { + if ((((u32) var_v0_4->unk0 >> 0x1F) == 0) || (var_v0_4->unk4 != var_a3_2->entries[0].id)) { + var_v0_4 += 0x148; + if (var_v0_4 != &gSequenceChannels) { goto loop_47; } } - if (phi_v0_4 == &D_803B1A30) { - temp_a3->unk0 = 0; - phi_v0_9 = 0; + if (var_v0_4 == &gSequenceChannels) { + var_a3_2->nextSide = 0; + var_v0_3 = 0; goto block_84; } goto block_52; } block_52: - if (phi_t2_2 == 2) { - phi_v0_5 = &D_803B1510; + if (var_t2 == 2) { + var_v0_5 = &gSequencePlayers; loop_54: - phi_v0_6 = phi_v0_5; - if (((phi_v0_5->unk0 >> 0x1F) == 0) || (phi_v0_5->unk4 != temp_a3->unk2A)) { - temp_v0_5 = phi_v0_5 + 0x148; - phi_v0_5 = temp_v0_5; - phi_v0_6 = temp_v0_5; - if (temp_v0_5 != &D_803B1A30) { + if ((((u32) var_v0_5->unk0 >> 0x1F) == 0) || (var_v0_5->unk4 != var_a3_2->entries[1].id)) { + var_v0_5 += 0x148; + if (var_v0_5 != &gSequenceChannels) { goto loop_54; } } - if (phi_v0_6 == &D_803B1A30) { - temp_a3->unk0 = 1; - phi_v0_9 = 1; + var_v0_3 = 1; + if (var_v0_5 == &gSequenceChannels) { + var_a3_2->nextSide = 1; goto block_84; } goto block_76; } goto block_76; } - if (sp20 == 1) { - if (phi_t1_2 == 2) { + if (sp20 == (s32) 1U) { + if (var_t1 == 2) { temp_a1_3 = gMaxSimultaneousNotes; - phi_v1_5 = 0; - phi_v1_6 = 0; + var_v1_4 = 0; if (temp_a1_3 > 0) { - phi_v0_7 = D_803B1508; + var_v0_6 = gNotes; loop_63: - phi_v1_6 = phi_v1_5; - if ((phi_v0_7->unkB2 != temp_a3->unk1E) || ((phi_v0_7->unkB0 >> 0x1F) == 0)) { - temp_v1_3 = phi_v1_5 + 1; - phi_v0_7 += 0xC0; - phi_v1_5 = temp_v1_3; - phi_v1_6 = temp_v1_3; - if (temp_v1_3 < temp_a1_3) { + if ((var_v0_6->unkB2 != var_a3_2->entries[0].id) || (((u32) var_v0_6->unkB0 >> 0x1F) == 0)) { + var_v1_4 += 1; + var_v0_6 += 0xC0; + if (var_v1_4 < temp_a1_3) { goto loop_63; } } } - phi_a2 = temp_a3->unk1E; - phi_a2_2 = temp_a3->unk1E; - if (phi_v1_6 == temp_a1_3) { - temp_a3->unk0 = 0; - phi_v0_9 = 0; + var_v0_3 = 0; + if (var_v1_4 == temp_a1_3) { + var_a3_2->nextSide = 0; goto block_84; } goto block_68; } block_68: - phi_a2 = phi_a2_2; - phi_a2 = phi_a2_2; - if (phi_t2_2 == 2) { + if (var_t2 == 2) { temp_a1_4 = gMaxSimultaneousNotes; - phi_v1_7 = 0; - phi_v1_8 = 0; + var_v1_5 = 0; if (temp_a1_4 > 0) { - phi_v0_8 = D_803B1508; + var_v0_7 = gNotes; loop_71: - phi_v1_8 = phi_v1_7; - if ((phi_v0_8->unkB2 != temp_a3->unk2A) || ((phi_v0_8->unkB0 >> 0x1F) == 0)) { - temp_v1_4 = phi_v1_7 + 1; - phi_v0_8 += 0xC0; - phi_v1_7 = temp_v1_4; - phi_v1_8 = temp_v1_4; - if (temp_v1_4 < temp_a1_4) { + if ((var_v0_7->unkB2 != var_a3_2->entries[1].id) || (((u32) var_v0_7->unkB0 >> 0x1F) == 0)) { + var_v1_5 += 1; + var_v0_7 += 0xC0; + if (var_v1_5 < temp_a1_4) { goto loop_71; } } } - if (phi_v1_8 == temp_a1_4) { - temp_a3->unk0 = 1; - phi_v0_9 = 1; + var_v0_3 = 1; + if (var_v1_5 == temp_a1_4) { + var_a3_2->nextSide = 1; goto block_84; } goto block_76; @@ -617,227 +432,180 @@ loop_71: goto block_76; } block_76: - temp_v0_6 = temp_a3->unk0; - phi_v0_9 = temp_v0_6; - if (temp_v0_6 == 0) { - if (phi_t1_2 == 1) { - if (phi_t2_2 != 1) { - temp_a3->unk0 = 1; - phi_v0_9 = 1; + var_v0_3 = var_a3_2->nextSide; + if (var_v0_3 == 0) { + if (var_t1 == 1) { + var_v0_3 = 1; + if (var_t2 != 1) { + var_a3_2->nextSide = 1; goto block_84; } goto block_83; } goto block_84; } - if (phi_t2_2 == 1) { - if (phi_t1_2 != 1) { - temp_a3->unk0 = 0; - phi_v0_9 = 0; + if (var_t2 == 1) { + var_v0_3 = 0; + if (var_t1 != 1) { + var_a3_2->nextSide = 0; goto block_84; } block_83: - return 0; + return NULL; } block_84: - temp_v1_5 = (temp_a3 + (phi_v0_9 * 0xC))->unk1E; - if (temp_v1_5 != -1) { - *(sp34 + temp_v1_5) = 0; - if (sp20 == 1) { - arg4 = arg4; - sp28 = temp_a3; - func_800B8EA8((temp_a3 + (temp_a3->unk0 * 0xC))->unk1E, sp20, phi_a2, temp_a3); - phi_ra = arg4; + temp_v1_2 = var_a3_2->entries[var_v0_3].id; + if (temp_v1_2 != -1) { + *(sp34 + temp_v1_2) = 0; + if (sp20 == (s32) 1U) { + sp28 = var_a3_2; + discard_bank(var_a3_2->entries[var_a3_2->nextSide].id, sp20, var_a3_2->entries[0].id, var_a3_2); } } - temp_a0_2 = (arg0 + 0x194)->unk0; - temp_v1_6 = arg0 + 0x198; - phi_a3_2 = arg0 + 0x194; - phi_a3_3 = arg0 + 0x194; - phi_v1_10 = temp_v1_6; - phi_a3_5 = arg0 + 0x194; - phi_a3_4 = arg0 + 0x194; + temp_a0_2 = var_a3_2->nextSide; + temp_v1_3 = &arg0->temporary.pool; if (temp_a0_2 != 0) { - temp_v1_7 = arg0 + 0x198; - phi_v1_9 = temp_v1_7; + temp_v1_4 = &arg0->temporary.pool; if (temp_a0_2 != 1) { - return 0; + return NULL; } - (arg0 + 0x194)->unk2A = phi_ra; - temp_v0_7 = ((temp_v1_7->unk0 + temp_v1_7->unk8) - arg2) - 0x10; - (arg0 + 0x194)->unk20 = temp_v0_7; - (arg0 + 0x194)->unk24 = arg2; - phi_v0_10 = temp_v0_7; - if (temp_v0_7 < temp_v1_7->unk4) { - *(sp34 + (arg0 + 0x194)->unk1E) = 0; - if (sp20 != 0) { - if (sp20 != phi_t4) { - - } else { - sp28 = arg0 + 0x194; - sp24 = temp_v1_7; - func_800B8EA8((arg0 + 0x194)->unk1E, sp20); - goto block_106; - } - } else { - sp28 = arg0 + 0x194; - sp24 = temp_v1_7; - func_800B8F8C((arg0 + 0x194)->unk1E, sp20); + var_a3_2->entries[1].id = (s16) id; + var_v0_8 = (&temp_v1_4->start[temp_v1_4->size] - size) - 0x10; + var_a3_2->entries[1].ptr = var_v0_8; + var_a3_2->entries[1].size = (u32) size; + if ((u32) var_v0_8 < (u32) temp_v1_4->cur) { + *(sp34 + var_a3_2->entries[0].id) = 0; + switch (sp20) { /* switch 1; irregular */ + case 0: /* switch 1 */ + sp28 = var_a3_2; + sp24 = temp_v1_4; + discard_sequence(var_a3_2->entries[0].id, sp20); block_106: - phi_a3_2 = sp28; - phi_v1_9 = arg0 + 0x198; + var_a3_2 = sp28; + break; + case 1: /* switch 1 */ + sp28 = var_a3_2; + sp24 = temp_v1_4; + discard_bank(var_a3_2->entries[0].id, sp20); + goto block_106; } - phi_a3_2->unk1E = -1; - phi_v1_9->unk4 = phi_v1_9->unk0; - phi_a3_4 = phi_a3_2; - phi_v0_10 = phi_a3_2->unk20; + var_a3_2->entries[0].id = -1; + temp_v1_4->cur = temp_v1_4->start; + var_v0_8 = var_a3_2->entries[1].ptr; } - phi_v1_11 = phi_v0_10; + var_v1 = var_v0_8; goto block_99; } - (arg0 + 0x194)->unk1E = phi_ra; - (arg0 + 0x194)->unk14 = temp_v1_6->unk0; - (arg0 + 0x194)->unk18 = arg2; - temp_v0_8 = temp_v1_6->unk0 + arg2; - temp_v1_6->unk4 = temp_v0_8; - if ((arg0 + 0x194)->unk20 < temp_v0_8) { - *(sp34 + (arg0 + 0x194)->unk2A) = 0; - if (sp20 != 0) { - if (sp20 != phi_t4) { - - } else { - sp28 = arg0 + 0x194; - sp24 = temp_v1_6; - func_800B8EA8((arg0 + 0x194)->unk2A, sp20); - goto block_96; - } - } else { - sp28 = arg0 + 0x194; - sp24 = temp_v1_6; - func_800B8F8C((arg0 + 0x194)->unk2A, sp20); + var_a3_2->entries[0].id = (s16) id; + var_a3_2->entries[0].ptr = temp_v1_3->start; + var_a3_2->entries[0].size = (u32) size; + temp_v0_3 = &temp_v1_3->start[size]; + temp_v1_3->cur = temp_v0_3; + if ((u32) var_a3_2->entries[1].ptr < (u32) temp_v0_3) { + *(sp34 + var_a3_2->entries[1].id) = 0; + switch (sp20) { /* irregular */ + case 0: + sp28 = var_a3_2; + sp24 = temp_v1_3; + discard_sequence(var_a3_2->entries[1].id, sp20); block_96: - phi_a3_3 = sp28; - phi_v1_10 = arg0 + 0x198; + var_a3_2 = sp28; + break; + case 1: + sp28 = var_a3_2; + sp24 = temp_v1_3; + discard_bank(var_a3_2->entries[1].id, sp20); + goto block_96; } - phi_a3_3->unk2A = -1; - phi_a3_3->unk20 = phi_v1_10->unk0 + phi_v1_10->unk8; - phi_a3_5 = phi_a3_3; + var_a3_2->entries[1].id = -1; + var_a3_2->entries[1].ptr = &temp_v1_3->start[temp_v1_3->size]; } - phi_a3_4 = phi_a3_5; - phi_v1_11 = phi_a3_5->unk14; + var_v1 = var_a3_2->entries[0].ptr; block_99: - *phi_a3_4 = *phi_a3_4 ^ 1; - return phi_v1_11; + var_a3_2->nextSide ^= 1; + return var_v1; } - arg4 = arg4; - arg3 = phi_a3; - temp_v0_9 = soundAlloc(arg0 + 4, arg1 * arg2); - (arg0 + (*arg0 * 0xC))->unk14 = temp_v0_9; - if (temp_v0_9 == 0) { + arg3 = var_a3; + temp_v0_4 = soundAlloc(&arg0->persistent.pool, arg1 * size); + arg0->persistent.entries[arg0->persistent.numEntries].ptr = temp_v0_4; + if (temp_v0_4 == NULL) { if ((arg3 != 0) && (arg3 != 1)) { if (arg3 == 2) { - phi_a3 = 0; + var_a3 = 0; goto loop_1; } goto block_116; } - return 0; + return NULL; } block_116: - (arg0 + (*arg0 * 0xC))->unk1E = arg4; - (arg0 + (*arg0 * 0xC))->unk18 = arg2; - temp_v1_8 = *arg0; - temp_v0 = (arg0 + (temp_v1_8 * 0xC))->unk14; - *arg0 = temp_v1_8 + 1; - return temp_v0; + arg0->persistent.entries[arg0->persistent.numEntries].id = (s16) id; + arg0->persistent.entries[arg0->persistent.numEntries].size = (u32) size; + temp_v1 = arg0->persistent.numEntries; + arg0->persistent.numEntries = temp_v1 + 1; + return arg0->persistent.entries[temp_v1].ptr; } #else GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B93BC.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -u32 func_800B9AD8(s32, s32, s32); // extern -s32 func_800BA858(s32); // extern +void *get_bank_or_seq(s32 poolIdx, s32 arg1, s32 id) { + void *ret; -void func_800B9A90(s32 arg0, s32 arg1, s32 arg2) { - if (func_800BA858(arg2) != 0) { - return; + ret = unk_pool1_lookup(poolIdx, id); + if (ret != NULL) { + return ret; } - func_800B9AD8(arg0, arg1, arg2); + return get_bank_or_seq_inner(poolIdx, arg1, id); } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B9A90.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -u32 func_800B9A90(s32, ?, s32); // extern -extern u32 D_803AFC48; -extern u32 D_803AFE18; -extern u32 D_803AFFE8; +void *get_bank_or_seq_inner(s32 poolIdx, s32 arg1, s32 bankId) { + u32 i; + struct SoundMultiPool* loadedPool; + struct TemporaryPool* temporary; + struct PersistentPool* persistent; -u32 func_800B9AD8(s32 arg0, s32 arg1, s32 arg2) { - u32 temp_v0; - void *temp_v1; - u32 *phi_a1; - u32 *phi_v1; - u32 phi_v0; - u32 phi_v0_2; + switch (poolIdx) { + case 0: + loadedPool = &gSeqLoadedPool; + break; + case 1: + loadedPool = &gBankLoadedPool; + break; + case 2: + loadedPool = &gUnusedLoadedPool; + break; + } - if (arg0 != 0) { - if (arg0 != 1) { - if (arg0 != 2) { - phi_a1 = sp18; - } else { - phi_a1 = &D_803AFFE8; - } + temporary = &loadedPool->temporary; + if (arg1 == 0) { + if (temporary->entries[0].id == bankId) { + temporary->nextSide = 1; + return temporary->entries[0].ptr; + } else if (temporary->entries[1].id == bankId) { + temporary->nextSide = 0; + return temporary->entries[1].ptr; } else { - phi_a1 = &D_803AFE18; + return NULL; } - } else { - phi_a1 = &D_803AFC48; } - temp_v1 = phi_a1 + 0x194; - if (arg1 == 0) { - if (arg2 == temp_v1->unk1E) { - temp_v1->unk0 = 1; - return temp_v1->unk14; - } - if (arg2 == temp_v1->unk2A) { - temp_v1->unk0 = 0; - return temp_v1->unk20; - } - return 0; - } - phi_v1 = phi_a1; - phi_v0 = 0; - phi_v0_2 = 0; - if (*phi_a1 != 0) { -loop_14: - if (arg2 == phi_v1->unk1E) { - return phi_v1->unk14; - } - temp_v0 = phi_v0 + 1; - phi_v1 += 0xC; - phi_v0 = temp_v0; - if (temp_v0 >= *phi_a1) { - goto block_17; + + persistent = &loadedPool->persistent; + for (i = 0; i < persistent->numEntries; i++) { + if (persistent->entries[i].id == bankId) { + return persistent->entries[i].ptr; } - goto loop_14; } -block_17: + if (arg1 == 2) { - phi_v0_2 = func_800B9A90(arg0, 0, arg0); + return get_bank_or_seq(poolIdx, 0, bankId); } - return phi_v0_2; + return NULL; } -#else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B9AD8.s") -#endif #ifdef MIPS_TO_C -UNUSED void func_800B9BE4(f32 arg0, f32 arg1, void *arg2) { +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +void func_800B9BE4(f32 arg0, f32 arg1, u16 *arg2) { ? sp4C; f32 sp30; f32 sp2C; @@ -846,22 +614,20 @@ UNUSED void func_800B9BE4(f32 arg0, f32 arg1, void *arg2) { f32 spC; ? *var_a0; f32 *var_a0_2; - f32 temp_f0; f32 temp_f10; f32 temp_f6; f32 temp_f8; - s16 *var_v1; - void *var_v1_2; + u16 *var_v1; + u16 *var_v1_2; - temp_f0 = D_800F2E80; var_a0 = &sp14; var_v1 = arg2 + 4; - spC = arg1 * temp_f0; - sp2C = arg0 * temp_f0; - sp10 = arg1 * arg0 * temp_f0; - sp30 = ((arg0 * arg0) + arg1) * temp_f0; + spC = arg1 * 262159.0f; + sp2C = arg0 * 262159.0f; + sp10 = arg1 * arg0 * 262159.0f; + sp30 = ((arg0 * arg0) + arg1) * 262159.0f; do { - *var_v1 = (s16) (u32) ((var_a0->unk-4 * arg0) + (arg1 * var_a0->unk-8)); + *var_v1 = (u16) (u32) ((var_a0->unk-4 * arg0) + (arg1 * var_a0->unk-8)); temp_f8 = var_a0->unk18; temp_f10 = var_a0->unk1C * arg0; var_a0 += 4; @@ -871,7 +637,7 @@ UNUSED void func_800B9BE4(f32 arg0, f32 arg1, void *arg2) { var_v1_2 = arg2; var_a0_2 = &spC; do { - var_v1_2->unk0 = (s16) (u32) var_a0_2->unk0; + var_v1_2->unk0 = (u16) (u32) var_a0_2->unk0; var_v1_2->unk2 = (s16) (u32) var_a0_2->unk4; var_v1_2->unk4 = (s16) (u32) var_a0_2->unk8; temp_f6 = var_a0_2->unkC; @@ -914,9 +680,9 @@ GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B9FB8.s") //generated by mips_to_c commit bd0364fa19633bd6201f8007e2d0a7ed87825909 void func_800B9FB8(); /* extern */ void func_800BA250(); /* extern */ -void func_800BEF2C(? *); /* extern */ -extern u32 D_803B1510; -extern ? D_803B1A30; +void sequence_player_disable(? *); /* extern */ +extern u32 gSequencePlayers; +extern ? gSequenceChannels; extern ? gAudioBufferParameters; s32 func_800BA00C(void) { @@ -941,12 +707,12 @@ s32 func_800BA00C(void) { temp_t6 = D_803B0500; switch (temp_t6) { case 5: - phi_s0 = &D_803B1510; + phi_s0 = &gSequencePlayers; do { - func_800BEF2C(phi_s0); + sequence_player_disable(phi_s0); temp_s0 = phi_s0 + 0x148; phi_s0 = temp_s0; - } while (temp_s0 != &D_803B1A30); + } while (temp_s0 != &gSequenceChannels); D_803B0504 = 4; D_803B0500 += -1; break; @@ -963,11 +729,11 @@ s32 func_800BA00C(void) { if (temp_a2 > 0) { do { temp_a0 = phi_a0 + 1; - temp_v0_2 = D_803B1508 + phi_v1; + temp_v0_2 = gNotes + phi_v1; phi_a0 = temp_a0; if (((temp_v0_2->unkB0 >> 0x1F) != 0) && (temp_v0_2->unk59 != 0)) { temp_v0_2->unk68 = gAudioBufferParameters.unk18; - temp_v0_3 = D_803B1508 + phi_v1; + temp_v0_3 = gNotes + phi_v1; temp_v0_3->unk58 = temp_v0_3->unk58 | 0x10; phi_a2 = gMaxSimultaneousNotes; } @@ -1027,187 +793,160 @@ GLOBAL_ASM("asm/non_matchings/audio/heap/func_800BA00C.s") #endif #ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800B8DE0(); // extern -s32 soundAlloc(? *, s32); // extern -void func_800B914C(? *, s16, s16, u16); // extern -void func_800B91C8(? *); // extern -void func_800B9244(? *); // extern -void func_800B9300(? *); // extern -void func_800BB030(s32); // extern -void func_800BD368(); // extern -void func_800BDD34(); // extern -extern ? D_800EA4D8; -extern s16 D_800EA5CC; -extern f32 D_800F2E98; -extern f32 D_800F2E9C; -extern ? D_803AF790; -extern ? D_803AFBB0; -extern u16 D_803AFBC0; -extern u8 D_803AFBC3; -extern s32 D_803AFBC4; +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +? func_800B8DE0(); /* extern */ +? func_800B914C(? *, s16, s16, u16); /* extern */ +? init_note_free_list(); /* extern */ +? note_init_all(); /* extern */ extern s32 D_803AFBD0; -extern ? gNotesAndBuffersPool; extern ? D_803B0348; -extern ? D_803B0358; -extern ? D_803B0360; -extern ? D_803B0370; +extern struct PoolSplit2 D_803B0358; +extern struct PoolSplit D_803B0360; +extern struct PoolSplit D_803B0370; extern u8 D_803B0501; -extern s32 D_803B1508; -extern s32 gSampleDmaNumListItems; -extern ? gAudioBufferParameters; +extern void *gNotes; extern s32 D_803B70AC; -extern s32 gMaxSimultaneousNotes; extern s16 D_803B70B4; extern ? D_803B70C8; -extern s32 D_803B70D0; +extern ? D_803B70D0; extern f32 D_803B7178; extern s32 D_803B717C; +extern ? sAudioSynthesisPad; +static ? D_800EA4D8; /* unable to generate initializer; const */ +static s16 D_800EA5CC; /* unable to generate initializer; const */ void func_800BA250(void) { - ? *temp_s0_2; + ? *var_s0; f32 temp_f0; + s16 *temp_v0_2; + s16 *temp_v0_3; s16 temp_a1; s16 temp_a2; s16 temp_t0; s16 temp_t1; s16 temp_v1; - s32 *temp_s6; - s32 temp_s0; - s32 temp_s1; - s32 temp_s1_2; - s32 temp_s5; s32 temp_t2; - s32 temp_t6; - s32 temp_t8; s32 temp_t9; - s32 temp_v0_2; - s32 temp_v0_3; + s32 var_s1; + s32 var_s5; + struct SynthesisReverb *var_s0_2; + struct SynthesisReverb *var_s2; + struct SynthesisReverb *var_s2_2; u16 temp_a3; u16 temp_t7; - u32 temp_s2; + u32 temp_s0; + u32 temp_s1; u8 temp_v1_2; + void *temp_s6; void *temp_v0; - ? *phi_s0; - ? *phi_s2; - s32 phi_s5; - ? *phi_s2_2; - ? *phi_s0_2; - s32 phi_s1; temp_s6 = (D_803B0501 * 0x28) + &D_800EA4D8; gSampleDmaNumListItems = 0; temp_t9 = temp_s6->unk0; - gAudioBufferParameters.unk2 = temp_t9; - gAudioBufferParameters.unk4 = osAiSetFrequency(temp_t9 & 0xFFFF); - temp_a3 = gAudioBufferParameters.unk2; - gAudioBufferParameters.unk6 = ((temp_a3 / D_803B717C) + 0xF) & 0xFFF0; - temp_v1 = gAudioBufferParameters.unk6; + gAudioBufferParameters.frequency = (u16) temp_t9; + gAudioBufferParameters.aiFrequency = osAiSetFrequency(temp_t9 & 0xFFFF); + temp_a3 = gAudioBufferParameters.frequency; + gAudioBufferParameters.samplesPerFrameTarget = (((s32) temp_a3 / (s32) D_803B717C) + 0xF) & 0xFFF0; + temp_v1 = gAudioBufferParameters.samplesPerFrameTarget; temp_t0 = temp_v1 + 0x10; - gAudioBufferParameters.unkA = temp_v1 - 0x10; - gAudioBufferParameters.unk8 = temp_t0; - gAudioBufferParameters.unkC = (temp_t0 / 0xC0) + 1; - temp_a2 = gAudioBufferParameters.unkC; - gAudioBufferParameters.unkE = (temp_v1 / temp_a2) & 0xFFF8; - temp_t1 = gAudioBufferParameters.unkE; - temp_f0 = temp_a2; - gAudioBufferParameters.unk10 = temp_t1 + 8; - gAudioBufferParameters.unk12 = temp_t1 - 8; - gAudioBufferParameters.unk14 = 32000.0f / temp_a3; - gAudioBufferParameters.unk1C = D_800F2E98 / temp_f0; - gAudioBufferParameters.unk18 = 1.0f / temp_f0; - gMaxSimultaneousNotes = temp_s6->unk5; - D_803AFBC0 = temp_s6->unkC; - D_803B70B4 = ((temp_f0 * D_800F2E9C) / D_800EA5CC) / D_803B7178; - gAudioBufferParameters.unk0 = temp_s6->unk4; - temp_a1 = gAudioBufferParameters.unk0; - gAudioBufferParameters.unk6 = temp_v1 * temp_a1; - gAudioBufferParameters.unk8 = gAudioBufferParameters.unk8 * temp_a1; - gAudioBufferParameters.unkA = gAudioBufferParameters.unkA * temp_a1; - gAudioBufferParameters.unkC = temp_a2 * temp_a1; - D_803B70AC = (gMaxSimultaneousNotes * 0x14 * gAudioBufferParameters.unkC) + (temp_s6->unk6 << 5) + 0x1E0; + gAudioBufferParameters.minAiBufferLength = temp_v1 - 0x10; + gAudioBufferParameters.maxAiBufferLength = temp_t0; + gAudioBufferParameters.updatesPerFrame = (temp_t0 / 192) + 1; + temp_a2 = gAudioBufferParameters.updatesPerFrame; + gAudioBufferParameters.samplesPerUpdate = (temp_v1 / temp_a2) & 0xFFF8; + temp_t1 = gAudioBufferParameters.samplesPerUpdate; + temp_f0 = (f32) temp_a2; + gAudioBufferParameters.samplesPerUpdateMax = temp_t1 + 8; + gAudioBufferParameters.samplesPerUpdateMin = temp_t1 - 8; + gAudioBufferParameters.resampleRate = 32000.0f / (f32) temp_a3; + gAudioBufferParameters.unkUpdatesPerFrameScaled = 0.001171875f / temp_f0; + gAudioBufferParameters.updatesPerFrameInv = 1.0f / temp_f0; + gMaxSimultaneousNotes = (s32) temp_s6->unk5; + gVolume = (s16) temp_s6->unkC; + D_803B70B4 = (s16) (u32) (((temp_f0 * 2880000.0f) / (f32) D_800EA5CC) / D_803B7178); + gAudioBufferParameters.presetUnk4 = (s16) temp_s6->unk4; + temp_a1 = gAudioBufferParameters.presetUnk4; + gAudioBufferParameters.samplesPerFrameTarget = temp_v1 * temp_a1; + gAudioBufferParameters.maxAiBufferLength *= temp_a1; + gAudioBufferParameters.minAiBufferLength *= temp_a1; + gAudioBufferParameters.updatesPerFrame = temp_a2 * temp_a1; + D_803B70AC = (gMaxSimultaneousNotes * 0x14 * gAudioBufferParameters.updatesPerFrame) + (temp_s6->unk6 << 5) + 0x1E0; temp_s0 = temp_s6->unk10 + temp_s6->unk14 + temp_s6->unk18; temp_s1 = temp_s6->unk1C + temp_s6->unk20 + temp_s6->unk24; temp_t2 = temp_s0 + temp_s1; - D_803B0348.unk0 = (D_803AFBD0 - temp_t2) - 0x100; + D_803B0348.unk0 = (s32) ((D_803AFBD0 - temp_t2) - 0x100); D_803B0348.unkC = temp_t2; func_800B914C(&D_803B0348, temp_a1, temp_a2, temp_a3); - D_803B0358.unk0 = temp_s0; - D_803B0358.unk4 = temp_s1; - func_800B91C8(&D_803B0358); - D_803B0360.unk0 = temp_s6->unk10; - D_803B0360.unk4 = temp_s6->unk14; - D_803B0360.unk8 = temp_s6->unk18; - func_800B9244(&D_803B0360); - D_803B0370.unk0 = temp_s6->unk1C; - D_803B0370.unk4 = temp_s6->unk20; - D_803B0370.unk8 = temp_s6->unk24; - func_800B9300(&D_803B0370); + D_803B0358.wantPersistent = temp_s0; + D_803B0358.wantTemporary = temp_s1; + seq_and_bank_pool_init(&D_803B0358); + D_803B0360.wantSeq = temp_s6->unk10; + D_803B0360.wantBank = temp_s6->unk14; + D_803B0360.wantUnused = temp_s6->unk18; + persistent_pools_init(&D_803B0360); + D_803B0370.wantSeq = temp_s6->unk1C; + D_803B0370.wantBank = temp_s6->unk20; + D_803B0370.wantUnused = temp_s6->unk24; + temporary_pools_init(&D_803B0370); func_800B8DE0(); - D_803B1508 = soundAlloc(&gNotesAndBuffersPool, gMaxSimultaneousNotes * 0xC0); - func_800BDD34(); - func_800BD368(); - D_803AFBC4 = soundAlloc(&gNotesAndBuffersPool, gAudioBufferParameters.unkC * gMaxSimultaneousNotes * 0x10); - phi_s0 = &D_803B70C8; + gNotes = soundAlloc(&gNotesAndBuffersPool, gMaxSimultaneousNotes * 0xC0); + note_init_all(); + init_note_free_list(); + gNoteSubsEu = soundAlloc(&gNotesAndBuffersPool, gAudioBufferParameters.updatesPerFrame * gMaxSimultaneousNotes * 0x10); + var_s0 = &D_803B70C8; do { - temp_s0_2 = phi_s0 + 4; - temp_s0_2->unk-4 = soundAlloc(&gNotesAndBuffersPool, D_803B70AC * 8); - phi_s0 = temp_s0_2; - } while (temp_s0_2 != &D_803B70D0); - phi_s2 = &D_803AF790; + var_s0 += 4; + var_s0->unk-4 = soundAlloc(&gNotesAndBuffersPool, D_803B70AC * 8); + } while (var_s0 != &D_803B70D0); + var_s2 = gSynthesisReverbs; do { - temp_s2 = phi_s2 + 0x108; - temp_s2->unk-107 = 0; - phi_s2 = temp_s2; - } while (temp_s2 < &D_803AFBB0); - D_803AFBC3 = temp_s6->unk6; - phi_s5 = 0; - phi_s2_2 = &D_803AF790; - if (D_803AFBC3 > 0) { + var_s2 += 0x108; + var_s2->unk-107 = 0; + } while ((u32) var_s2 < (u32) &sAudioSynthesisPad); + gNumSynthesisReverbs = (s8) temp_s6->unk6; + var_s2_2 = gSynthesisReverbs; + var_s5 = 0; + if (gNumSynthesisReverbs > 0) { do { - temp_v0 = temp_s6->unk8 + (phi_s5 * 4); + temp_v0 = temp_s6->unk8 + (var_s5 * 4); temp_t7 = temp_v0->unk1 << 6; - phi_s2_2->unk6 = temp_t7; - phi_s2_2->unk4 = temp_v0->unk0; - phi_s2_2->unk1 = 8; - phi_s2_2->unk8 = temp_v0->unk2; - phi_s2_2->unk18 = soundAlloc(&gNotesAndBuffersPool, (temp_t7 & 0xFFFF) * 2); - temp_v1_2 = phi_s2_2->unk4; - phi_s2_2->unk1C = soundAlloc(&gNotesAndBuffersPool, phi_s2_2->unk6 * 2); - phi_s2_2->unkC = 0; - phi_s2_2->unk10 = 0; - phi_s2_2->unk3 = 0; - phi_s2_2->unk2 = 2; - phi_s2_2->unk14 = phi_s2_2->unk6; + var_s2_2->windowSize = temp_t7; + var_s2_2->downsampleRate = temp_v0->unk0; + var_s2_2->useReverb = 8; + var_s2_2->reverbGain = temp_v0->unk2; + var_s2_2->ringBuffer.left = soundAlloc(&gNotesAndBuffersPool, (temp_t7 & 0xFFFF) * 2); + temp_v1_2 = var_s2_2->downsampleRate; + var_s2_2->ringBuffer.right = soundAlloc(&gNotesAndBuffersPool, var_s2_2->windowSize * 2); + var_s2_2->nextRingBufferPos = 0; + var_s2_2->unkC = 0; + var_s2_2->curFrame = 0; + var_s2_2->framesLeftToIgnore = 2; + var_s2_2->bufSizePerChannel = (s32) var_s2_2->windowSize; if (temp_v1_2 != 1) { - phi_s2_2->unk0 = 1; - phi_s2_2->unkA = 0x8000 / temp_v1_2; - phi_s2_2->unk20 = soundAlloc(&gNotesAndBuffersPool, 0x20); - phi_s2_2->unk24 = soundAlloc(&gNotesAndBuffersPool, 0x20); - phi_s2_2->unk28 = soundAlloc(&gNotesAndBuffersPool, 0x20); - phi_s2_2->unk2C = soundAlloc(&gNotesAndBuffersPool, 0x20); - phi_s1 = 0; - if (gAudioBufferParameters.unkC > 0) { - phi_s0_2 = phi_s2_2; + var_s2_2->resampleFlags = 1; + var_s2_2->resampleRate = (u16) (0x8000 / (s32) temp_v1_2); + var_s1 = 0; + var_s2_2->resampleStateLeft = soundAlloc(&gNotesAndBuffersPool, 0x00000020U); + var_s2_2->resampleStateRight = soundAlloc(&gNotesAndBuffersPool, 0x00000020U); + var_s2_2->unk24 = soundAlloc(&gNotesAndBuffersPool, 0x00000020U); + var_s2_2->unk28 = soundAlloc(&gNotesAndBuffersPool, 0x00000020U); + if (gAudioBufferParameters.updatesPerFrame > 0) { + var_s0_2 = var_s2_2; do { - temp_v0_2 = soundAlloc(&gNotesAndBuffersPool, 0x300); - temp_t6 = temp_v0_2 + 0x180; - phi_s0_2->unk34 = temp_v0_2; - phi_s0_2->unk38 = temp_t6; - temp_v0_3 = soundAlloc(&gNotesAndBuffersPool, 0x300); - temp_t8 = temp_v0_3 + 0x180; - phi_s0_2->unk98 = temp_v0_3; - phi_s0_2->unk9C = temp_t8; - temp_s1_2 = phi_s1 + 1; - phi_s0_2 += 0x14; - phi_s1 = temp_s1_2; - } while (temp_s1_2 < gAudioBufferParameters.unkC); + temp_v0_2 = soundAlloc(&gNotesAndBuffersPool, 0x00000300U); + var_s0_2->items[0][0].toDownsampleLeft = temp_v0_2; + var_s0_2->items[0][0].toDownsampleRight = temp_v0_2 + 0x180; + temp_v0_3 = soundAlloc(&gNotesAndBuffersPool, 0x00000300U); + var_s0_2->items[1][0].toDownsampleLeft = temp_v0_3; + var_s0_2->items[1][0].toDownsampleRight = temp_v0_3 + 0x180; + var_s1 += 1; + var_s0_2 += 0x14; + } while (var_s1 < gAudioBufferParameters.updatesPerFrame); } } - temp_s5 = phi_s5 + 1; - phi_s5 = temp_s5; - phi_s2_2 += 0x108; - } while (temp_s5 < D_803AFBC3); + var_s5 += 1; + var_s2_2 += 0x108; + } while (var_s5 < gNumSynthesisReverbs); } func_800BB030(gMaxSimultaneousNotes); osWritebackDCacheAll(); @@ -1216,36 +955,101 @@ void func_800BA250(void) { GLOBAL_ASM("asm/non_matchings/audio/heap/func_800BA250.s") #endif +void *unk_pool1_lookup(s32 poolIdx, s32 id) { + s32 i; + + for (i = 0; i < gUnkPool1.pool.numAllocatedEntries; i++) { + if (gUnkPool1.entries[i].poolIndex == poolIdx && gUnkPool1.entries[i].id == id) { + return gUnkPool1.entries[i].ptr; + } + } + return NULL; +} + #ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern ? D_803B01B8; -extern s32 D_803B01C4; +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +? audio_dma_copy_immediate(s32, u8 *, u32, s32); /* extern */ +? func_800BB584(s32); /* extern */ +extern ? gBankLoadStatus; +extern ? gSeqLoadStatus; +extern s32 D_803B706C; +extern s32 D_803B7070; +extern s32 D_803B7074; +extern s32 gCtlEntries; -s32 func_800BA858(s32 arg0, s32 arg1) { - s32 temp_v0; - s32 temp_v1; - ? *phi_a1; - s32 phi_v0; +void func_800BA8B0(s16 arg0, s32 arg1) { + s32 sp3C; + s32 sp38; + u32 sp34; + s32 sp30; + void *sp20; + s32 temp_a2; + s32 var_a3; + s32 var_s1; + u32 temp_a1; + u8 *temp_v0_3; + u8 *temp_v0_4; + u8 *temp_v0_5; + void *temp_v0; + void *temp_v0_2; - temp_v1 = D_803B01C4; - phi_v0 = 0; - if (temp_v1 > 0) { - phi_a1 = &D_803B01B8; -loop_2: - temp_v0 = phi_v0 + 1; - phi_v0 = temp_v0; - if ((arg0 == phi_a1->unk18) && (arg1 == phi_a1->unk1A)) { - return phi_a1->unk10; + var_s1 = arg1; + switch (arg0) { /* irregular */ + case 0: + sp3C = D_803B706C; + break; + case 1: + sp3C = D_803B7070; + break; + case 2: + sp3C = D_803B7074; + break; + } + temp_v0 = sp3C + (var_s1 * 8); + if (temp_v0->unk8 == 0) { + var_s1 = temp_v0->unk4; + } + if (unk_pool1_lookup((s32) arg0, var_s1) == NULL) { + temp_v0_2 = sp3C + (var_s1 * 8); + temp_a2 = gUnkPool1.pool.numAllocatedEntries; + temp_a1 = temp_v0_2->unk8; + var_a3 = temp_v0_2->unk4; + if (arg0 == 1) { + var_a3 += 0x10; } - phi_a1 += 0xC; - if (temp_v0 >= temp_v1) { - // Duplicate return node #6. Try simplifying control flow for better match - return 0; + sp34 = temp_a1; + sp38 = temp_a2; + sp30 = var_a3; + temp_v0_3 = soundAlloc(&gUnkPool1.pool, temp_a1); + gUnkPool1.entries[temp_a2].ptr = temp_v0_3; + if (temp_v0_3 != NULL) { + sp20 = (temp_a2 * 0xC) + &gUnkPool1; + audio_dma_copy_immediate(var_a3, temp_v0_3, sp34, var_a3); + gUnkPool1.entries[temp_a2].poolIndex = arg0; + gUnkPool1.entries[temp_a2].id = (s16) var_s1; + gUnkPool1.entries[temp_a2].size = sp34; + switch (arg0) { /* switch 1; irregular */ + case 0: /* switch 1 */ + temp_v0_4 = var_s1 + &gSeqLoadStatus; + if (*temp_v0_4 != 5) { + *temp_v0_4 = 5; + return; + } + break; + case 1: /* switch 1 */ + (gCtlEntries + (var_s1 * 0xC))->unk4 = (u8 *) (gUnkPool1.entries[temp_a2].ptr + 4); + func_800BB584(var_s1); + temp_v0_5 = var_s1 + &gBankLoadStatus; + if (*temp_v0_5 != 5) { + *temp_v0_5 = 5; + } + break; + } } - goto loop_2; + } else { + case 2: /* switch 1 */ } - return 0; } #else -GLOBAL_ASM("asm/non_matchings/audio/heap/func_800BA858.s") +GLOBAL_ASM("asm/non_matchings/audio/heap/func_800BA8B0.s") #endif diff --git a/src/audio/heap.h b/src/audio/heap.h index 7ca2f2b3d..f3e32c08a 100644 --- a/src/audio/heap.h +++ b/src/audio/heap.h @@ -22,6 +22,103 @@ struct SoundAllocPool { s32 numAllocatedEntries; }; // size = 0x10 +struct SeqOrBankEntry { + u8 *ptr; + u32 size; + s16 poolIndex; + s16 id; +}; // size = 0xC + +struct PersistentPool { + /*0x00*/ u32 numEntries; + /*0x04*/ struct SoundAllocPool pool; + /*0x14*/ struct SeqOrBankEntry entries[32]; +}; // size = 0x194 + +struct TemporaryPool { + /*EU, SH*/ + /*0x00, 0x00*/ u32 nextSide; + /*0x04, */ struct SoundAllocPool pool; + /*0x04, pool.start */ + /*0x08, pool.cur */ + /*0x0C, 0x0C pool.size */ + /*0x10, 0x10 pool.numAllocatedEntries */ + /*0x14, */ struct SeqOrBankEntry entries[2]; + /*0x14, 0x14 entries[0].ptr */ + /*0x18, entries[0].size*/ + /*0x1C, 0x1E entries[0].id */ + /*0x20, 0x20 entries[1].ptr */ + /*0x24, entries[1].size*/ + /*0x28, 0x2A entries[1].id */ +}; // size = 0x2C + +struct SoundMultiPool { + /*0x000*/ struct PersistentPool persistent; + /*0x194*/ struct TemporaryPool temporary; + /* */ u32 pad2[4]; +}; // size = 0x1D0 + +struct Unk1Pool { + struct SoundAllocPool pool; + struct SeqOrBankEntry entries[32]; +}; + +struct UnkEntry { + s8 used; + s8 medium; + s8 bankId; + u32 pad; + u8 *srcAddr; + u8 *dstAddr; + u32 size; +}; + +struct UnkPool { + /*0x00*/ struct SoundAllocPool pool; + /*0x10*/ struct UnkEntry entries[64]; + /*0x510*/ s32 numEntries; + /*0x514*/ u32 unk514; +}; + +struct PoolSplit { + u32 wantSeq; + u32 wantBank; + u32 wantUnused; + u32 wantCustom; +}; // size = 0x10 + +struct PoolSplit2 { + u32 wantPersistent; + u32 wantTemporary; +}; // size = 0x8 + +void discard_bank(s32 bankId); +void discard_sequence(s32 seqId); +void *soundAlloc(struct SoundAllocPool *pool, u32 size); +void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size); +void persistent_pool_clear(struct PersistentPool *persistent); +void temporary_pool_clear(struct TemporaryPool *temporary); +void *get_bank_or_seq(s32 poolIdx, s32 arg1, s32 id); +void *get_bank_or_seq_inner(s32 poolIdx, s32 arg1, s32 bankId); +void func_800B90E0(struct SoundAllocPool *pool); +void seq_and_bank_pool_init(struct PoolSplit2 *a); +void persistent_pools_init(struct PoolSplit *a); +void temporary_pools_init(struct PoolSplit *a); +void *unk_pool1_lookup(s32 poolIdx, s32 id); + +// Note: In some .asm files D_803AFBC8 has been replaced with gLeftVolRampings +// That is almost certainly incorrect, but I don't know how to fix it at this point +extern struct SoundAllocPool gAudioSessionPool; // D_803AFBC8 +extern struct SoundAllocPool gAudioInitPool; // D_803AFBD8 extern struct SoundAllocPool gNotesAndBuffersPool; +extern struct SoundAllocPool gPersistentCommonPool; // D_803AFC28 +extern struct SoundAllocPool gTemporaryCommonPool; // D_803AFC38 +extern struct SoundMultiPool gSeqLoadedPool; // D_803AFC48 +extern struct SoundMultiPool gBankLoadedPool; // D_803AFE18 +extern struct Unk1Pool gUnkPool1; // D_803B01B8 +extern u8 gBankLoadStatus[64]; // D_803B03C0 +extern u8 gSeqLoadStatus[256]; // D_803B0400 +extern struct SoundMultiPool gUnusedLoadedPool; // D_803AFFE8 +extern struct SoundAllocPool gSeqAndBankPool; // D_803AFC18 -#endif // AUDIO_HEAP_H
\ No newline at end of file +#endif // AUDIO_HEAP_H diff --git a/src/audio/internal.h b/src/audio/internal.h index f9bbc5593..a9aaa4628 100644 --- a/src/audio/internal.h +++ b/src/audio/internal.h @@ -1,8 +1,51 @@ #ifndef AUDIO_INTERNAL_H #define AUDIO_INTERNAL_H -#include <PR/ultratypes.h> +#include <ultra64.h> +#include "types.h" + +#define SEQUENCE_PLAYERS 4 +#define SEQUENCE_CHANNELS 48 +#define SEQUENCE_LAYERS 64 + +#define LAYERS_MAX 4 +#define CHANNELS_MAX 16 + +#define NO_LAYER ((struct SequenceChannelLayer *)(-1)) + +#define MUTE_BEHAVIOR_STOP_SCRIPT 0x80 // stop processing sequence/channel scripts +#define MUTE_BEHAVIOR_STOP_NOTES 0x40 // prevent further notes from playing +#define MUTE_BEHAVIOR_SOFTEN 0x20 // lower volume, by default to half + +#define SEQUENCE_PLAYER_STATE_0 0 +#define SEQUENCE_PLAYER_STATE_FADE_OUT 1 +#define SEQUENCE_PLAYER_STATE_2 2 +#define SEQUENCE_PLAYER_STATE_3 3 +#define SEQUENCE_PLAYER_STATE_4 4 + +#define NOTE_PRIORITY_DISABLED 0 +#define NOTE_PRIORITY_STOPPING 1 +#define NOTE_PRIORITY_MIN 2 +#define NOTE_PRIORITY_DEFAULT 3 + +#define TATUMS_PER_BEAT 48 + +// abi.h contains more details about the ADPCM and S8 codecs, "skip" skips codec processing +#define CODEC_ADPCM 0 +#define CODEC_S8 1 +#define CODEC_SKIP 2 + +#define TEMPO_SCALE TATUMS_PER_BEAT + +// TODO: US_FLOAT should probably be renamed to JP_DOUBLE since eu seems to use floats too +#define US_FLOAT(x) x ## f +#define US_FLOAT2(x) x + +// Convert u8 or u16 to f32. On JP, this uses a u32->f32 conversion, +// resulting in more bloated codegen, while on US it goes through s32. +// Since u8 and u16 fit losslessly in both, behavior is the same. +#define FLOAT_CAST(x) (f32) (s32) (x) // No-op printf macro which leaves string literals in rodata in IDO. IDO // doesn't support variadic macros, so instead we let the parameter list @@ -15,11 +58,59 @@ #define stubbed_printf(...) #endif -#define stubbed_printf_0(msg) stubbed_printf(msg) -#define stubbed_printf_1(msg, a) stubbed_printf(msg, a) -#define stubbed_printf_2(msg, a, b) stubbed_printf(msg, a, b) -#define stubbed_printf_3(msg, a, b, c) stubbed_printf(msg, a, b, c) +#define eu_stubbed_printf_0(msg) stubbed_printf(msg) +#define eu_stubbed_printf_1(msg, a) stubbed_printf(msg, a) +#define eu_stubbed_printf_2(msg, a, b) stubbed_printf(msg, a, b) +#define eu_stubbed_printf_3(msg, a, b, c) stubbed_printf(msg, a, b, c) + +struct NotePool; + +struct AudioListItem { + // A node in a circularly linked list. Each node is either a head or an item: + // - Items can be either detached (prev = NULL), or attached to a list. + // 'value' points to something of interest. + // - List heads are always attached; if a list is empty, its head points + // to itself. 'count' contains the size of the list. + // If the list holds notes, 'pool' points back to the pool where it lives. + // Otherwise, that member is NULL. + struct AudioListItem *prev; + struct AudioListItem *next; + union { + void *value; // either Note* or SequenceChannelLayer* + s32 count; + } u; + struct NotePool *pool; +}; // size = 0x10 + +struct NotePool { + struct AudioListItem disabled; + struct AudioListItem decaying; + struct AudioListItem releasing; + struct AudioListItem active; +}; + +struct VibratoState { + /*0x00, 0x00*/ struct SequenceChannel *seqChannel; + /*0x04, 0x04*/ u32 time; + /* , 0x08*/ s16 *curve; + /* , 0x0C*/ f32 extent; + /* , 0x10*/ f32 rate; + /* , 0x14*/ u8 active; + /*0x12, 0x16*/ u16 rateChangeTimer; + /*0x14, 0x18*/ u16 extentChangeTimer; + /*0x16, 0x1A*/ u16 delay; +}; // size = 0x18, 0x1C on EU +// Pitch sliding by up to one octave in the positive direction. Negative +// direction is "supported" by setting extent to be negative. The code +// extrapolates exponentially in the wrong direction in that case, but that +// doesn't prevent seqplayer from doing it, AFAICT. +struct Portamento { + u8 mode; // bit 0x80 denotes something; the rest are an index 0-5 + f32 cur; + f32 speed; + f32 extent; +}; // size = 0x10 struct AdsrEnvelope { s16 delay; @@ -54,8 +145,269 @@ struct AudioBankSound { f32 tuning; // frequency scale factor }; // size = 0x8 -struct NoteSub -{ +struct Instrument { + /*0x00*/ u8 loaded; + /*0x01*/ u8 normalRangeLo; + /*0x02*/ u8 normalRangeHi; + /*0x03*/ u8 releaseRate; + /*0x04*/ struct AdsrEnvelope *envelope; + /*0x08*/ struct AudioBankSound lowNotesSound; + /*0x10*/ struct AudioBankSound normalNotesSound; + /*0x18*/ struct AudioBankSound highNotesSound; +}; // size = 0x20 + +struct Drum { + u8 releaseRate; + u8 pan; + u8 loaded; + struct AudioBankSound sound; + struct AdsrEnvelope *envelope; +}; + +struct AudioBank { + struct Drum **drums; + struct Instrument *instruments[1]; +}; // dynamic size + +struct CtlEntry { + u8 unused; + u8 numInstruments; + u8 numDrums; + struct Instrument **instruments; + struct Drum **drums; +}; // size = 0xC + +struct M64ScriptState { + u8 *pc; + u8 *stack[4]; + u8 remLoopIters[4]; + u8 depth; +}; // size = 0x1C + +// Also known as a Group, according to debug strings. +struct SequencePlayer { + /*US/JP, EU, SH */ + /*0x000, 0x000, 0x000*/ u8 enabled : 1; + /*0x000, 0x000*/ u8 finished : 1; // never read + /*0x000, 0x000*/ u8 muted : 1; + /*0x000, 0x000*/ u8 seqDmaInProgress : 1; + /*0x000, 0x000*/ u8 bankDmaInProgress : 1; + /* 0x000*/ u8 recalculateVolume : 1; + /*0x002, 0x001, 0x001*/ u8 state; + /*0x003, 0x002*/ u8 noteAllocPolicy; + /*0x004, 0x003*/ u8 muteBehavior; + /*0x005, 0x004*/ u8 seqId; + /*0x006, 0x005*/ u8 defaultBank[1]; // must be an array to get a comparison + // to match; other u8's might also be part of that array + /*0x007, 0x006*/ u8 loadingBankId; + /* , 0x007, 0x007*/ s8 seqVariationEu[1]; + /*0x00A, 0x008*/ u16 tempo; // beats per minute in JP, tatums per minute in US/EU + /*0x00C, 0x00A*/ u16 tempoAcc; + /*0x010, 0x00C, 0x00E*/ s16 transposition; + /*0x012, 0x00E, 0x010*/ u16 delay; + /*0x00E, 0x010, 0x012*/ u16 fadeRemainingFrames; + /* , 0x012, 0x014*/ u16 fadeTimerUnkEu; + /*0x014, 0x014*/ u8 *seqData; // buffer of some sort + /*0x018, 0x018, 0x1C*/ f32 fadeVolume; // set to 1.0f + /*0x01C, 0x01C*/ f32 fadeVelocity; // set to 0.0f + /*0x020, 0x020, 0x024*/ f32 volume; // set to 0.0f + /*0x024, 0x024*/ f32 muteVolumeScale; // set to 0.5f + /* , 0x028, 0x02C*/ f32 fadeVolumeScale; + /* , 0x02C*/ f32 appliedFadeVolume; + /*0x02C, 0x030, 0x034*/ struct SequenceChannel *channels[CHANNELS_MAX]; + /*0x06C, 0x070*/ struct M64ScriptState scriptState; + /*0x088, 0x08C*/ u8 *shortNoteVelocityTable; + /*0x08C, 0x090*/ u8 *shortNoteDurationTable; + /*0x090, 0x094*/ struct NotePool notePool; + /*0x0D0, 0x0D4*/ OSMesgQueue seqDmaMesgQueue; + /*0x0E8, 0x0EC*/ OSMesg seqDmaMesg; + /*0x0EC, 0x0F0*/ OSIoMesg seqDmaIoMesg; + /*0x100, 0x108*/ OSMesgQueue bankDmaMesgQueue; + /*0x118, 0x120*/ OSMesg bankDmaMesg; + /*0x11C, 0x124*/ OSIoMesg bankDmaIoMesg; + /*0x130, 0x13C*/ u8 *bankDmaCurrMemAddr; + /*0x138, 0x140*/ uintptr_t bankDmaCurrDevAddr; + /*0x13C, 0x144*/ ssize_t bankDmaRemaining; +}; // size = 0x140, 0x148 on EU, 0x14C on SH + +struct AdsrSettings { + u8 releaseRate; + u8 sustain; + struct AdsrEnvelope *envelope; +}; // size = 0x8 + +struct AdsrState { + /*0x00, 0x00*/ u8 action; + /*0x01, 0x01*/ u8 state; + /*0x08, 0x02*/ s16 envIndex; + /*0x0A, 0x04*/ s16 delay; + /* , 0x08*/ f32 sustain; + /* , 0x0C*/ f32 velocity; + /* , 0x10*/ f32 fadeOutVel; + /* , 0x14*/ f32 current; + /* , 0x18*/ f32 target; + s32 pad1C; + /*0x1C, 0x20*/ struct AdsrEnvelope *envelope; +}; // size = 0x20, 0x24 in EU + +struct ReverbBitsData { + /* 0x00 */ u8 bit0 : 1; + /* 0x00 */ u8 bit1 : 1; + /* 0x00 */ u8 bit2 : 1; + /* 0x00 */ u8 usesHeadsetPanEffects : 1; + /* 0x00 */ u8 stereoHeadsetEffects : 2; + /* 0x00 */ u8 strongRight : 1; + /* 0x00 */ u8 strongLeft : 1; +}; + +union ReverbBits { + /* 0x00 */ struct ReverbBitsData s; + /* 0x00 */ u8 asByte; +}; +struct ReverbInfo { + u8 reverbVol; + u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 + u8 pan; + union ReverbBits reverbBits; + f32 freqScale; + f32 velocity; + s32 unused; + s16 *filter; +}; + +struct NoteAttributes { + u8 reverbVol; + u8 pan; + f32 freqScale; + f32 velocity; +}; // size = 0x10 + +// Also known as a SubTrack, according to debug strings. +// Confusingly, a SubTrack is a container of Tracks. +struct SequenceChannel { + /* U/J, EU, SH */ + /*0x00, 0x00*/ u8 enabled : 1; + /*0x00, 0x00*/ u8 finished : 1; + /*0x00, 0x00*/ u8 stopScript : 1; + /*0x00, 0x00*/ u8 stopSomething2 : 1; // sets SequenceChannelLayer.stopSomething + /*0x00, 0x00*/ u8 hasInstrument : 1; + /*0x00, 0x00*/ u8 stereoHeadsetEffects : 1; + /*0x00, ????*/ u8 largeNotes : 1; // notes specify duration and velocity + /*0x00, ????*/ u8 unused : 1; // never read, set to 0 + /* , 0x01*/ union { + struct { + u8 freqScale : 1; + u8 volume : 1; + u8 pan : 1; + } as_bitfields; + u8 as_u8; + } changes; + /*0x01, 0x02*/ u8 noteAllocPolicy; + /*0x02, 0x03, 0x03*/ u8 muteBehavior; + /*0x03, 0x04, 0x04*/ u8 reverbVol; // until EU: Q1.7, after EU: UQ0.8 + /*0x04, ????*/ u8 notePriority; // 0-3 + /*0x05, 0x06*/ u8 bankId; + /* , 0x07*/ u8 reverbIndex; + /* , 0x08, 0x09*/ u8 bookOffset; + /* , 0x09*/ u8 newPan; + /* , 0x0A*/ u8 panChannelWeight; // proportion of pan that comes from the channel (0..128) + /*0x08, 0x0C, 0x0E*/ u16 vibratoRateStart; // initially 0x800 + /*0x0A, 0x0E, 0x10*/ u16 vibratoExtentStart; + /*0x0C, 0x10, 0x12*/ u16 vibratoRateTarget; // initially 0x800 + /*0x0E, 0x12, 0x14*/ u16 vibratoExtentTarget; + /*0x10, 0x14, 0x16*/ u16 vibratoRateChangeDelay; + /*0x12, 0x16, 0x18*/ u16 vibratoExtentChangeDelay; + /*0x14, 0x18, 0x1A*/ u16 vibratoDelay; + /*0x16, 0x1A, 0x1C*/ u16 delay; + /*0x18, 0x1C, 0x1E*/ s16 instOrWave; // either 0 (none), instrument index + 1, or + // 0x80..0x83 for sawtooth/triangle/sine/square waves. + /*0x1A, 0x1E, 0x20*/ s16 transposition; + /*0x1C, 0x20, 0x24*/ f32 volumeScale; + /*0x20, 0x24, 0x28*/ f32 volume; + /* , 0x28*/ s32 pan; + /* , 0x2C*/ f32 appliedVolume; + /*0x2C, 0x30*/ f32 freqScale; + /*0x30, 0x34*/ u8 (*dynTable)[][2]; + /*0x34, ????*/ struct Note *noteUnused; // never read + /*0x38, ????*/ struct SequenceChannelLayer *layerUnused; // never read + /*0x3C, 0x40*/ struct Instrument *instrument; + /*0x40, 0x44*/ struct SequencePlayer *seqPlayer; + /*0x44, 0x48*/ struct SequenceChannelLayer *layers[LAYERS_MAX]; + /*0x54, 0x58 */ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2, + // [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment + /*0x5C, 0x60*/ struct M64ScriptState scriptState; + /*0x78, 0x7C*/ struct AdsrSettings adsr; + /*0x80, 0x84*/ struct NotePool notePool; +}; // size = 0xC0, 0xC4 in EU, 0xD0 in SH + +// Also known as a Track, according to debug strings. +struct SequenceChannelLayer { + /* U/J, EU, SH */ + /*0x00, 0x00*/ u8 enabled : 1; + /*0x00, 0x00*/ u8 finished : 1; + /*0x00, 0x00*/ u8 stopSomething : 1; // ? + /*0x00, 0x00*/ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound + /* , 0x00*/ u8 unusedEu0b8 : 1; + /* , 0x00*/ u8 notePropertiesNeedInit : 1; + /* , 0x00*/ u8 ignoreDrumPan : 1; + /* , 0x01, 0x02*/ u8 instOrWave; + /*0x01, 0x02, 0x03*/ u8 status; // 0x03 in SH + /*0x02, 0x03*/ u8 noteDuration; // set to 0x80 + /*0x03, 0x04*/ u8 portamentoTargetNote; + /* , 0x05*/ u8 pan; // 0..128 + /* , 0x06, 0x07*/ u8 notePan; + /*0x04, 0x08*/ struct Portamento portamento; + /*0x14, 0x18*/ struct AdsrSettings adsr; + /*0x1C, 0x20*/ u16 portamentoTime; + /*0x1E, 0x22*/ s16 transposition; // #semitones added to play commands + // (m64 instruction encoding only allows referring to the limited range + // 0..0x3f; this makes 0x40..0x7f accessible as well) + /*0x20, 0x24, 0x24*/ f32 freqScale; + /*0x24, 0x28, 0x2C*/ f32 velocitySquare; + /*0x2C, 0x2C, 0x30*/ f32 noteVelocity; + /*0x34, 0x30, 0x34*/ f32 noteFreqScale; + /*0x38, 0x34*/ s16 shortNoteDefaultPlayPercentage; + /*0x3A, 0x36*/ s16 playPercentage; // it's not really a percentage... + /*0x3C, 0x38*/ s16 delay; + /*0x3E, 0x3A*/ s16 duration; + /*0x40, 0x3C*/ s16 delayUnused; // set to 'delay', never read + /*0x44, 0x40, 0x44*/ struct Note *note; + /*0x48, 0x44*/ struct Instrument *instrument; + /*0x4C, 0x48*/ struct AudioBankSound *sound; + /*0x50, 0x4C, 0x50*/ struct SequenceChannel *seqChannel; + /*0x54, 0x50*/ struct M64ScriptState scriptState; + /*0x70, 0x6C*/ struct AudioListItem listItem; + u8 pad2[4]; +}; // size = 0x80 + +struct NoteSynthesisState { + /*0x00*/ u8 restart; + /*0x01*/ u8 sampleDmaIndex; + /*0x02*/ u8 prevHeadsetPanRight; + /*0x03*/ u8 prevHeadsetPanLeft; + /*0x04, 0x06*/ u16 samplePosFrac; + /*0x08*/ s32 samplePosInt; + /*0x0C*/ struct NoteSynthesisBuffers *synthesisBuffers; + /*0x10*/ s16 curVolLeft; // UQ0.16 (EU Q1.15) + /*0x12*/ s16 curVolRight; // UQ0.16 (EU Q1.15) +}; +struct NotePlaybackState { + /* U/J, EU, SH */ + /*0x04, 0x00, 0x00*/ u8 priority; + /* 0x01, 0x01*/ u8 waveId; + /* 0x02, 0x02*/ u8 sampleCountIndex; + /*0x08, 0x04, 0x06*/ s16 adsrVolScale; + /*0x18, 0x08, 0x08*/ f32 portamentoFreqScale; + /*0x1C, 0x0C, 0x0C*/ f32 vibratoFreqScale; + /*0x28, 0x10, */ struct SequenceChannelLayer *prevParentLayer; + /*0x2C, 0x14, 0x14*/ struct SequenceChannelLayer *parentLayer; + /*0x30, 0x18, 0x18*/ struct SequenceChannelLayer *wantedParentLayer; + /* , 0x1C, 0x1C*/ struct NoteAttributes attributes; + /*0x54, 0x28, 0x2C*/ struct AdsrState adsr; + /*0x74, 0x4C, */ struct Portamento portamento; + /*0x84, 0x5C, */ struct VibratoState vibratoState; +}; +struct NoteSubEu { /*0x00*/ volatile u8 enabled : 1; /*0x00*/ u8 needsInit : 1; /*0x00*/ u8 finished : 1; @@ -71,15 +423,98 @@ struct NoteSub /*0x02*/ u8 bankId; /*0x03*/ u8 headsetPanRight; /*0x04*/ u8 headsetPanLeft; - /*0x05*/ u8 reverbVol; - /*0x06*/ u16 targetVolLeft; - /*0x08*/ u16 targetVolRight; + /*0x05*/ u8 reverbVol; // UQ0.7 (EU Q1.7) + /*0x06*/ u16 targetVolLeft; // UQ0.12 (EU UQ0.10) + /*0x08*/ u16 targetVolRight; // UQ0.12 (EU UQ0.10) /*0x0A*/ u16 resamplingRateFixedPoint; // stored as signed but loaded as u16 /*0x0C*/ union { s16 *samples; struct AudioBankSound *audioBankSound; } sound; }; +struct Note { + /* U/J, EU, SH */ + /*0xA4, 0x00, 0x00*/ struct AudioListItem listItem; + /* 0x10, 0x10*/ struct NoteSynthesisState synthesisState; + // The next members are actually part of a struct (NotePlaybackState), but + // that results in messy US/EU ifdefs. Instead we cast to a struct pointer + // when needed... This breaks alignment on non-N64 platforms, which we hack + // around by skipping the padding in that case. + // TODO: use macros or something instead. +#ifdef TARGET_N64 + u8 pad0[12]; +#endif + + /*0x04, 0x30, 0x30*/ u8 priority; + /* 0x31, 0x31*/ u8 waveId; + /* 0x32, 0x32*/ u8 sampleCountIndex; + /*0x08, 0x34, 0x36*/ s16 adsrVolScale; + /*0x18, 0x38, */ f32 portamentoFreqScale; + /*0x1C, 0x3C, */ f32 vibratoFreqScale; + /*0x28, 0x40, */ struct SequenceChannelLayer *prevParentLayer; + /*0x2C, 0x44, 0x44*/ struct SequenceChannelLayer *parentLayer; + /*0x30, 0x48, 0x48*/ struct SequenceChannelLayer *wantedParentLayer; + /* , 0x4C, 0x4C*/ struct NoteAttributes attributes; + /*0x54, 0x58, 0x5C*/ struct AdsrState adsr; + /*0x74, 0x7C*/ struct Portamento portamento; + /*0x84, 0x8C*/ struct VibratoState vibratoState; + u8 pad3[8]; + /* , 0xB0, 0xB4*/ struct NoteSubEu noteSubEu; +}; // size = 0xC0, known to be 0xC8 on SH + +// While this struct needs to be size 0xA0, its not clear +// what innards are necessary. All the possible options from +// SM64 are sized incorrectly so we're probably looking at some +// MK64 weirdness +struct NoteSynthesisBuffers { + s16 adpcmdecState[0x10]; + s16 finalResampleState[0x10]; + s16 panResampleState[0x10]; + s16 panSamplesBuffer[0x20]; +}; // size = 0xA0 + +/* +SM64 NoteSynthesisBuffers, kept here because I'm not sure our current +version is correct +struct NoteSynthesisBuffers { + s16 adpcmdecState[0x10]; + s16 finalResampleState[0x10]; +#ifdef VERSION_SH + s16 unk[0x10]; + s16 filterBuffer[0x20]; + s16 panSamplesBuffer[0x20]; +#else + s16 mixEnvelopeState[0x28]; + s16 panResampleState[0x10]; + s16 panSamplesBuffer[0x20]; + s16 dummyResampleState[0x10]; +#if defined(VERSION_JP) || defined(VERSION_US) + s16 samples[0x40]; +#endif +#endif +}; +*/ + +struct ReverbSettingsEU { + u8 downsampleRate; + u8 windowSize; // To be multiplied by 64 + u16 gain; +}; + +struct AudioSessionSettingsEU { + /* 0x00 */ u32 frequency; + /* 0x04 */ u8 unk1; // always 1 + /* 0x05 */ u8 maxSimultaneousNotes; + /* 0x06 */ u8 numReverbs; // always 1 + /* 0x07 */ u8 unk2; // always 0 + /* 0x08 */ struct ReverbSettingsEU *reverbSettings; + /* 0x0C */ u16 volume; + /* 0x0E */ u16 unk3; // always 0 + /* 0x10 */ u32 persistentSeqMem; + /* 0x14 */ u32 persistentBankMem; + /* 0x18, 0x1C */ u32 temporarySeqMem; + /* 0x1C, 0x20 */ u32 temporaryBankMem; +}; // 0x30 on shindou struct AudioSessionSettings { /*0x00*/ u32 frequency; @@ -110,4 +545,43 @@ struct AudioBufferParametersEU { /*0x1C*/ f32 unkUpdatesPerFrameScaled; // 3.0f / (1280.0f * updatesPerFrame) }; +struct EuAudioCmd { + union { +#if IS_BIG_ENDIAN + struct { + u8 op; + u8 arg1; + u8 arg2; + u8 arg3; + } s; +#else + struct { + u8 arg3; + u8 arg2; + u8 arg1; + u8 op; + } s; +#endif + s32 first; + } u; + union { + s32 as_s32; + u32 as_u32; + f32 as_f32; +#if IS_BIG_ENDIAN + u8 as_u8; + s8 as_s8; +#else + struct { + u8 pad0[3]; + u8 as_u8; + }; + struct { + u8 pad1[3]; + s8 as_s8; + }; #endif + } u2; +}; + +#endif // AUDIO_INTERNAL_H diff --git a/src/audio/load.c b/src/audio/load.c index 9a6acddbe..88ecadf7a 100644 --- a/src/audio/load.c +++ b/src/audio/load.c @@ -1,9 +1,10 @@ #include <ultra64.h> #include <macros.h> -#include "load.h" -#include "data.h" -#include "heap.h" -#include "internal.h" +#include "audio/load.h" +#include "audio/data.h" +#include "audio/heap.h" +#include "audio/internal.h" +#include "audio/playback.h" #define ALIGN16(val) (((val) + 0xF) & ~0xF) struct SharedDma { @@ -35,20 +36,15 @@ extern u8 sSampleDmaReuseQueueTail2; // sSampleDmaReuseQueueTail2 extern u8 sSampleDmaReuseQueueHead1; // sSampleDmaReuseQueueHead1 extern u8 sSampleDmaReuseQueueHead2; // sSampleDmaReuseQueueHead2 - - -extern void *soundAlloc(struct SoundAllocPool *pool, u32 size); - /** * Performs an immediate DMA copy */ -// audio_dma_copy_immediate void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) { - stubbed_printf_3("Romcopy %x -> %x ,size %x\n", devAddr, vAddr, nbytes); + eu_stubbed_printf_3("Romcopy %x -> %x ,size %x\n", devAddr, vAddr, nbytes); osInvalDCache(vAddr, nbytes); osPiStartDma(&D_803B6740, OS_MESG_PRI_HIGH, OS_READ, devAddr, vAddr, nbytes, &D_803B6720); osRecvMesg(&D_803B6720, NULL, OS_MESG_BLOCK); - stubbed_printf_0("Romcopyend\n"); + eu_stubbed_printf_0("Romcopyend\n"); } const char audioString34[] = "CAUTION:WAVE CACHE FULL %d"; @@ -83,26 +79,16 @@ const char af[] = "Sorry,too many %d bank is none.fast load Start \n"; /** * Performs an asynchronus (normal priority) DMA copy */ -//audio_dma_copy_async -void func_800BAAF8(uintptr_t devAddr, void *vAddr, size_t nbytes, OSMesgQueue *queue, OSIoMesg *mesg) { +void audio_dma_copy_async(uintptr_t devAddr, void *vAddr, size_t nbytes, OSMesgQueue *queue, OSIoMesg *mesg) { osInvalDCache(vAddr, nbytes); osPiStartDma(mesg, OS_MESG_PRI_NORMAL, OS_READ, devAddr, vAddr, nbytes, queue); } -//#else -//GLOBAL_ASM("asm/non_matchings/audio/load/func_800BAAF8.s") -//#endif - -//#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -//s32 osPiStartDma(s32, ?, ?, s32, void *, u32, s32); // extern - /** * Performs a partial asynchronous (normal priority) DMA copy. This is limited * to 0x1000 bytes transfer at once. */ -// audio_dma_partial_copy_async -void func_800BAB58(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg) { +void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg) { ssize_t transfer = (*remaining >= 0x1000 ? 0x1000 : *remaining); *remaining -= transfer; osInvalDCache(*vAddr, transfer); @@ -110,13 +96,8 @@ void func_800BAB58(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQue *devAddr += transfer; *vAddr += transfer; } -//#else -//GLOBAL_ASM("asm/non_matchings/audio/load/func_800BAB58.s") -//#endif - -// decrease_sample_dma_ttls -void func_800BAC04() { +void decrease_sample_dma_ttls() { u32 i; for (i = 0; i < sSampleDmaListSize1; i++) { @@ -449,41 +430,35 @@ s32 func_800BB304(struct AudioBankSample *sample) { } } -#ifdef MIPS_TO_C -//generated by m2c commit b7eac665cffd02361f73cec283ef16d0a35a0e5b -void *func_800BC948(); /* extern */ -void *func_800BC9F8(s32); /* extern */ +s32 func_800BB388(s32 bankId, s32 instId, s32 arg2) { + struct Instrument *instr; + struct Drum *drum; -void func_800BB388(s32 arg0, s32 arg1, s32 arg2) { - void *sp1C; - void *temp_v0; - void *temp_v0_2; - - if (arg1 < 0x7F) { - temp_v0 = func_800BC948(); - if (temp_v0 == NULL) { - return; + if (instId < 0x7F) { + instr = get_instrument_inner(bankId, instId); + if (instr == NULL) { + return -1; } - if (temp_v0->unk1 != 0) { - sp1C = temp_v0; - func_800BB304(temp_v0->unk8); + if (instr->normalRangeLo != 0) { + func_800BB304(instr->lowNotesSound.sample); } - sp1C = temp_v0; - func_800BB304(temp_v0->unk10); - if (temp_v0->unk2 != 0x7F) { - func_800BB304(temp_v0->unk18); + func_800BB304(instr->normalNotesSound.sample); + if (instr->normalRangeHi != 0x7F) { + func_800BB304(instr->highNotesSound.sample); } - } else if (arg1 == 0x0000007F) { - temp_v0_2 = func_800BC9F8(arg2); - if (temp_v0_2 == NULL) { - return; + //! @bug missing return + } else if (instId == 0x7F) { + drum = get_drum(bankId, arg2); + if (drum == NULL) { + return -1; } - func_800BB304(temp_v0_2->unk4); + func_800BB304(drum->sound.sample); + return 0; } -} -#else -GLOBAL_ASM("asm/non_matchings/audio/load/func_800BB388.s") +#ifdef AVOID_UB + return 0; #endif +} #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 @@ -514,64 +489,45 @@ void func_800BB43C(void *arg0, s32 arg1) { GLOBAL_ASM("asm/non_matchings/audio/load/func_800BB43C.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 soundAlloc(? *, s32, s32); // extern -void audio_dma_copy_immediate(s32, s32, s32, s32); // extern -extern ? gNotesAndBuffersPool; +void patch_sound(struct AudioBankSound *sound, u8 *memBase, u8 *offsetBase) { + struct AudioBankSample *sample; + void *patched; + u8 *mem; -void func_800BB484(void **arg0, s32 arg1, s32 arg2) { - void *sp2C; - s32 sp28; - s32 sp24; - s32 temp_a3_2; - s32 temp_v0_2; - u8 temp_a0; - void *temp_a3; - void *temp_v0; +#define PATCH(x, base) (patched = (void *)((uintptr_t) (x) + (uintptr_t) base)) - temp_v0 = *arg0; - temp_a3 = temp_v0 + arg1; - if (temp_v0 != 0) { - *arg0 = temp_a3; - temp_a0 = temp_a3->unk1; - if (temp_a0 == 0) { - temp_a3->unk4 = temp_a3->unk4 + arg2; - temp_a3->unk8 = temp_a3->unk8 + arg1; - temp_a3->unkC = temp_a3->unkC + arg1; - temp_a3->unk1 = 1; - return; + if (sound->sample != NULL) { + sample = sound->sample = PATCH(sound->sample, memBase); + if (sample->loaded == 0) { + sample->sampleAddr = PATCH(sample->sampleAddr, offsetBase); + sample->loop = PATCH(sample->loop, memBase); + sample->book = PATCH(sample->book, memBase); + sample->loaded = 1; } - if (temp_a0 == 0x80) { - temp_a3_2 = temp_a3->unk4 + arg2; - sp28 = temp_a3_2; - sp2C = temp_a3; - temp_v0_2 = soundAlloc(&gNotesAndBuffersPool, temp_a3->unk10, temp_a3_2); - if (temp_v0_2 == 0) { - temp_a3->unk4 = temp_a3_2; - temp_a3->unk1 = 1; + else if (sample->loaded == 0x80) { + PATCH(sample->sampleAddr, offsetBase); + mem = soundAlloc(&gNotesAndBuffersPool, sample->sampleSize); + if (mem == NULL) { + sample->sampleAddr = patched; + sample->loaded = 1; } else { - sp24 = temp_v0_2; - sp2C = temp_a3; - audio_dma_copy_immediate(temp_a3_2, temp_v0_2, temp_a3->unk10, temp_a3_2); - temp_a3->unk1 = 0x81; - temp_a3->unk4 = temp_v0_2; + audio_dma_copy_immediate((uintptr_t) patched, mem, sample->sampleSize); + sample->loaded = 0x81; + sample->sampleAddr = mem; } - (temp_v0 + arg1)->unk8 = (temp_v0 + arg1)->unk8 + arg1; - (temp_v0 + arg1)->unkC = (temp_v0 + arg1)->unkC + arg1; + sample->loop = PATCH(sample->loop, memBase); + sample->book = PATCH(sample->book, memBase); } - // Duplicate return node #8. Try simplifying control flow for better match } + +#undef PATCH } -#else -GLOBAL_ASM("asm/non_matchings/audio/load/func_800BB484.s") -#endif #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BB624(s32, s32, u8, u8); // extern +void patch_audio_bank(s32, s32, u8, u8); // extern extern s32 D_803B7074; -extern s32 D_803B7080; +extern s32 gCtlEntries; void func_800BB584(s32 arg0) { s32 sp18; @@ -590,80 +546,84 @@ void func_800BB584(s32 arg0) { phi_a1 = temp_v0->unk4; } temp_v1_2 = arg0 * 0xC; - temp_v0_2 = D_803B7080 + temp_v1_2; + temp_v0_2 = gCtlEntries + temp_v1_2; sp18 = temp_v1_2; - func_800BB624(temp_v0_2->unk4 - 4, phi_a1, temp_v0_2->unk1, temp_v0_2->unk2); - temp_v0_3 = D_803B7080 + temp_v1_2; + patch_audio_bank(temp_v0_2->unk4 - 4, phi_a1, temp_v0_2->unk1, temp_v0_2->unk2); + temp_v0_3 = gCtlEntries + temp_v1_2; temp_v0_3->unk8 = temp_v0_3->unk4->unk-4; } #else GLOBAL_ASM("asm/non_matchings/audio/load/func_800BB584.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BB484(void *, void **, ?); // extern - -void func_800BB624(void **arg0, ? arg1, s32 arg2, s32 arg3) { - s32 temp_s2; - void **temp_s2_2; - void **temp_v0_2; - void *temp_s0; - void *temp_s0_2; - void *temp_t2; - void *temp_v0; - void *temp_v0_3; - s32 phi_s4; - s32 phi_s2; - void **phi_s2_2; - - temp_v0 = *arg0; - if ((temp_v0 != 0) && (arg3 != 0)) { - *arg0 = temp_v0 + arg0; - phi_s2 = 0; - if (arg3 != 0) { - phi_s4 = 0; - do { - temp_v0_2 = *arg0 + phi_s4; - temp_s0 = *temp_v0_2; - temp_s0_2 = temp_s0 + arg0; - if (temp_s0 != 0) { - *temp_v0_2 = temp_s0_2; - if (temp_s0_2->unk2 == 0) { - func_800BB484(temp_s0_2 + 4, arg0, arg1); - temp_s0_2->unk2 = 1; - temp_s0_2->unkC = temp_s0_2->unkC + arg0; - } +void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums) { + struct Instrument *instrument; + struct Instrument **itInstrs; + struct Instrument **end; + struct AudioBank *temp; + u32 i; + void *patched; + struct Drum *drum; + struct Drum **drums; + u32 numDrums2; + +#define BASE_OFFSET_REAL(x, base) (void *)((uintptr_t) (x) + (uintptr_t) base) +#define PATCH(x, base) (patched = BASE_OFFSET_REAL(x, base)) +#define PATCH_MEM(x) x = PATCH(x, mem) + +#define BASE_OFFSET(x, base) BASE_OFFSET_REAL(base, x) + + drums = mem->drums; + numDrums2 = numDrums; + if (drums != NULL && numDrums2 > 0) { + mem->drums = PATCH(drums, mem); + for (i = 0; i < numDrums2; i++) { + patched = mem->drums[i]; + if (patched != NULL) { + drum = PATCH(patched, mem); + mem->drums[i] = drum; + if (drum->loaded == 0) { + patch_sound(&drum->sound, (u8 *) mem, offset); + patched = drum->envelope; + drum->envelope = BASE_OFFSET(mem, patched); + drum->loaded = 1; } - temp_s2 = phi_s2 + 1; - phi_s4 += 4; - phi_s2 = temp_s2; - } while (temp_s2 != arg3); + + } } } - phi_s2_2 = arg0 + 4; - if (arg2 != 0) { + + //! Doesn't affect EU, but required for US/JP + temp = &*mem; + if (numInstruments > 0) { + //! Doesn't affect EU, but required for US/JP + struct Instrument **tempInst; + itInstrs = temp->instruments; + tempInst = temp->instruments; + end = numInstruments + tempInst; + do { - temp_v0_3 = *phi_s2_2; - temp_t2 = temp_v0_3 + arg0; - if (temp_v0_3 != 0) { - *phi_s2_2 = temp_t2; - if (temp_t2->unk0 == 0) { - func_800BB484(temp_t2 + 8, arg0, arg1); - func_800BB484(temp_t2 + 0x10, arg0, arg1); - func_800BB484(temp_t2 + 0x18, arg0, arg1); - temp_t2->unk0 = 1; - temp_t2->unk4 = temp_t2->unk4 + arg0; + if (*itInstrs != NULL) { + *itInstrs = BASE_OFFSET(*itInstrs, mem); + instrument = *itInstrs; + + if (instrument->loaded == 0) { + patch_sound(&instrument->lowNotesSound, (u8 *) mem, offset); + patch_sound(&instrument->normalNotesSound, (u8 *) mem, offset); + patch_sound(&instrument->highNotesSound, (u8 *) mem, offset); + patched = instrument->envelope; + instrument->envelope = BASE_OFFSET(mem, patched); + instrument->loaded = 1; } } - temp_s2_2 = phi_s2_2 + 4; - phi_s2_2 = temp_s2_2; - } while (((arg2 * 4) + arg0 + 4) != temp_s2_2); + itInstrs++; + } while (end != itInstrs); } +#undef PATCH_MEM +#undef PATCH +#undef BASE_OFFSET_REAL +#undef BASE_OFFSET } -#else -GLOBAL_ASM("asm/non_matchings/audio/load/func_800BB624.s") -#endif @@ -672,10 +632,10 @@ GLOBAL_ASM("asm/non_matchings/audio/load/func_800BB624.s") s32 func_800B93BC(? *, ?, s32, ?, s32); // extern void audio_dma_copy_immediate(s32, s32, s32); // extern void func_800BB584(s32); // extern -extern u32 D_803AFE18; -extern u8 D_803B03C0; +extern u32 gBankLoadedPool; +extern u8 gBankLoadStatus; extern s32 D_803B7070; -extern s32 D_803B7080; +extern s32 gCtlEntries; s32 func_800BB780(s32 arg0, ? arg1) { s32 sp54; @@ -690,15 +650,15 @@ s32 func_800BB780(s32 arg0, ? arg1) { temp_a2 = ((temp_v0->unk8 + 0x1E) & ~0xF) - 0x10; sp54 = temp_a2; sp28 = temp_v0->unk4; - temp_v0_2 = func_800B93BC(&D_803AFE18, 1, temp_a2, arg1, arg0); + temp_v0_2 = func_800B93BC(&gBankLoadedPool, 1, temp_a2, arg1, arg0); if (temp_v0_2 == 0) { return 0; } sp2C = temp_v0_2; audio_dma_copy_immediate(sp28 + 0x10, temp_v0_2, temp_a2); - (D_803B7080 + (arg0 * 0xC))->unk4 = sp2C + 4; + (gCtlEntries + (arg0 * 0xC))->unk4 = sp2C + 4; func_800BB584(arg0); - temp_v0_3 = arg0 + &D_803B03C0; + temp_v0_3 = arg0 + &gBankLoadStatus; if (*temp_v0_3 != 5) { *temp_v0_3 = 2; } @@ -711,11 +671,11 @@ GLOBAL_ASM("asm/non_matchings/audio/load/func_800BB780.s") #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 s32 func_800B93BC(? *, ?, s32, ?, s32); // extern -void func_800BAB58(void *, void *, void *, OSMesgQueue *, void *); // extern -extern u32 D_803AFE18; -extern u8 D_803B03C0; +void audio_dma_partial_copy_async(void *, void *, void *, OSMesgQueue *, void *); // extern +extern u32 gBankLoadedPool; +extern u8 gBankLoadStatus; extern s32 D_803B7070; -extern s32 D_803B7080; +extern s32 gCtlEntries; s32 func_800BB864(s32 arg0, ? arg1, void *arg2) { s32 sp64; @@ -733,24 +693,24 @@ s32 func_800BB864(s32 arg0, ? arg1, void *arg2) { temp_a2 = ((temp_v0->unk8 + 0x1E) & ~0xF) - 0x10; sp64 = temp_a2; sp38 = temp_v0->unk4; - temp_v0_2 = func_800B93BC(&D_803AFE18, 1, temp_a2, arg1, arg0); + temp_v0_2 = func_800B93BC(&gBankLoadedPool, 1, temp_a2, arg1, arg0); sp3C = temp_v0_2; if (temp_v0_2 == 0) { return 0; } arg2->unk6 = arg0; temp_v1 = arg0 * 0xC; - (D_803B7080 + temp_v1)->unk4 = temp_v0_2 + 4; + (gCtlEntries + temp_v1)->unk4 = temp_v0_2 + 4; temp_a3 = arg2 + 0x108; - (D_803B7080 + temp_v1)->unk8 = 0; + (gCtlEntries + temp_v1)->unk8 = 0; arg2->unk13C = temp_v0_2; arg2->unk144 = temp_a2; arg2->unk140 = sp38 + 0x10; sp2C = temp_a3; osCreateMesgQueue(temp_a3, arg2 + 0x120, 1); arg2->unk0 = arg2->unk0 | 8; - func_800BAB58(arg2 + 0x140, arg2 + 0x13C, arg2 + 0x144, temp_a3, arg2 + 0x124); - temp_v0_3 = arg0 + &D_803B03C0; + audio_dma_partial_copy_async(arg2 + 0x140, arg2 + 0x13C, arg2 + 0x144, temp_a3, arg2 + 0x124); + temp_v0_3 = arg0 + &gBankLoadStatus; if (*temp_v0_3 != 5) { *temp_v0_3 = 1; } @@ -764,8 +724,8 @@ GLOBAL_ASM("asm/non_matchings/audio/load/func_800BB864.s") //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 s32 func_800B93BC(? *, ?, s32, ?, s32); // extern void audio_dma_copy_immediate(s32, s32, s32); // extern -extern u32 D_803AFC48; -extern ? D_803B0400; +extern u32 gSeqLoadedPool; +extern ? gSeqLoadStatus; extern s32 D_803B706C; s32 func_800BB99C(s32 arg0, ? arg1) { @@ -781,13 +741,13 @@ s32 func_800BB99C(s32 arg0, ? arg1) { temp_t9 = (temp_v0_2->unk8 + 0xF) & ~0xF; sp2C = temp_t9; sp24 = temp_v0_2->unk4; - temp_v0 = func_800B93BC(&D_803AFC48, 1, temp_t9, arg1, arg0); + temp_v0 = func_800B93BC(&gSeqLoadedPool, 1, temp_t9, arg1, arg0); if (temp_v0 == 0) { return 0; } sp28 = temp_v0; audio_dma_copy_immediate(sp24, temp_v0, sp2C); - temp_v0_3 = arg0 + &D_803B0400; + temp_v0_3 = arg0 + &gSeqLoadStatus; if (*temp_v0_3 != 5) { *temp_v0_3 = 2; } @@ -801,9 +761,9 @@ GLOBAL_ASM("asm/non_matchings/audio/load/func_800BB99C.s") //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 s32 func_800B93BC(? *, ?, s32, ?, s32); // extern void audio_dma_copy_immediate(s32, s32, s32); // extern -void func_800BAAF8(s32, s32, s32, OSMesgQueue *, void *); // extern -extern u32 D_803AFC48; -extern ? D_803B0400; +void audio_dma_copy_async(s32, s32, s32, OSMesgQueue *, void *); // extern +extern u32 gSeqLoadedPool; +extern ? gSeqLoadStatus; extern s32 D_803B706C; s32 func_800BBA50(s32 arg0, ? arg1, u8 *arg2) { @@ -821,13 +781,13 @@ s32 func_800BBA50(s32 arg0, ? arg1, u8 *arg2) { temp_a2 = (temp_v0_2->unk8 + 0xF) & ~0xF; temp_s0 = temp_a2; sp3C = temp_v0_2->unk4; - temp_v0 = func_800B93BC(&D_803AFC48, 1, temp_a2, arg1, arg0); + temp_v0 = func_800B93BC(&gSeqLoadedPool, 1, temp_a2, arg1, arg0); if (temp_v0 == 0) { return 0; } if (temp_s0 < 0x41) { audio_dma_copy_immediate(sp3C, temp_v0, temp_s0); - temp_v0_3 = arg0 + &D_803B0400; + temp_v0_3 = arg0 + &gSeqLoadStatus; if (*temp_v0_3 != 5) { *temp_v0_3 = 2; } @@ -837,8 +797,8 @@ s32 func_800BBA50(s32 arg0, ? arg1, u8 *arg2) { sp34 = temp_a3; osCreateMesgQueue(temp_a3, arg2 + 0xEC, 1); *arg2 = *arg2 | 0x10; - func_800BAAF8(sp3C + 0x40, temp_v0 + 0x40, temp_s0 - 0x40, temp_a3, arg2 + 0xF0); - temp_v0_4 = arg0 + &D_803B0400; + audio_dma_copy_async(sp3C + 0x40, temp_v0 + 0x40, temp_s0 - 0x40, temp_a3, arg2 + 0xF0); + temp_v0_4 = arg0 + &gSeqLoadStatus; if (*temp_v0_4 != 5) { *temp_v0_4 = 1; } @@ -849,64 +809,42 @@ s32 func_800BBA50(s32 arg0, ? arg1, u8 *arg2) { GLOBAL_ASM("asm/non_matchings/audio/load/func_800BBA50.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800B9A90(s32, ?, u8); // extern -extern u8 D_803B03C0; -extern s32 D_803B7078; - -s32 func_800BBBA0(s32 arg0, s32 *arg1, s32 *arg2) { - s32 temp_v0; - u16 temp_s1; - u8 temp_s0; - u8 temp_s2; - u8 temp_t0; - s32 phi_s1; - s32 phi_v1; - u8 phi_s2; - s32 phi_s7; - s32 phi_s7_2; +u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) { + void *temp; + u32 bankId; + u16 offset; + u8 i; + u8 ret; + + *nullCount = 0; + *nonNullCount = 0; + offset = ((u16 *) gAlBankSets)[seqId]; + for (i = gAlBankSets[offset++], ret = 0; i != 0; i--) { + bankId = gAlBankSets[offset++]; + + if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { + temp = get_bank_or_seq(1, 2, bankId); + } else { + temp = NULL; + } - *arg2 = 0; - *arg1 = 0; - temp_v0 = D_803B7078; - temp_s1 = *(temp_v0 + (arg0 * 2)); - temp_s2 = *(temp_s1 + temp_v0); - phi_s1 = (temp_s1 + 1) & 0xFFFF; - phi_s2 = temp_s2; - phi_s7 = 0; - phi_s7_2 = 0; - if (temp_s2 != 0) { - do { - temp_s0 = *(phi_s1 + D_803B7078); - phi_s1 = (phi_s1 + 1) & 0xFFFF; - phi_v1 = 0; - if (((*(&D_803B03C0 + temp_s0) < 2) ^ 1) == 1) { - phi_v1 = func_800B9A90(1, 2, temp_s0); - } - if (phi_v1 == 0) { - *arg2 = *arg2 + 1; - phi_s7_2 = temp_s0 & 0xFF; - } else { - *arg1 = *arg1 + 1; - } - temp_t0 = (phi_s2 - 1) & 0xFF; - phi_s2 = temp_t0; - phi_s7 = phi_s7_2; - } while (temp_t0 != 0); + if (temp == NULL) { + (*nullCount)++; + ret = bankId; + } else { + (*nonNullCount)++; + } } - return phi_s7; + + return ret; } -#else -GLOBAL_ASM("asm/non_matchings/audio/load/func_800BBBA0.s") -#endif #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800B9A90(s32, ?, u8); // extern +s32 get_bank_or_seq(s32, ?, u8); // extern s32 func_800BB780(u8, ?); // extern -extern u8 D_803B03C0; -extern s32 D_803B7078; +extern u8 gBankLoadStatus; +extern s32 gAlBankSets; s32 func_800BBCD0(s32 arg0, s8 *arg1) { s32 sp34; @@ -921,18 +859,18 @@ s32 func_800BBCD0(s32 arg0, s8 *arg1) { u8 phi_s2; s32 phi_v1_2; - temp_v0 = D_803B7078; + temp_v0 = gAlBankSets; temp_s1 = *(temp_v0 + (arg0 * 2)); temp_s2 = *(temp_s1 + temp_v0); phi_s1 = (temp_s1 + 1) & 0xFFFF; phi_s2 = temp_s2; if (temp_s2 != 0) { do { - temp_s0 = *(phi_s1 + D_803B7078); + temp_s0 = *(phi_s1 + gAlBankSets); phi_s1 = (phi_s1 + 1) & 0xFFFF; phi_v1 = 0; - if (((*(&D_803B03C0 + temp_s0) < 2) ^ 1) == 1) { - phi_v1 = func_800B9A90(1, 2, temp_s0); + if (((*(&gBankLoadStatus + temp_s0) < 2) ^ 1) == 1) { + phi_v1 = get_bank_or_seq(1, 2, temp_s0); } phi_v1_2 = phi_v1; if (phi_v1 == 0) { @@ -953,11 +891,11 @@ GLOBAL_ASM("asm/non_matchings/audio/load/func_800BBCD0.s") #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800B9A90(?, ?, u32); // extern +s32 get_bank_or_seq(?, ?, u32); // extern s32 func_800BB99C(u32, ?, u32); // extern s32 func_800BBCD0(u32, ? *, u32); // extern extern s32 D_800EA5DC; -extern u8 D_803B03C0; +extern u8 gBankLoadStatus; extern s32 D_803B706C; extern u16 D_803B707C; @@ -989,9 +927,9 @@ void func_800BBDDC(u32 arg0, s32 arg1) { phi_a2_3 = phi_a2_2; if ((arg1 & 0xFF & 1) != 0) { phi_v1 = 0; - if (((*(&D_803B03C0 + phi_a2_2) < 2) ^ 1) == 1) { + if (((*(&gBankLoadStatus + phi_a2_2) < 2) ^ 1) == 1) { arg0 = phi_a2_2; - phi_v1 = func_800B9A90(0, 2, phi_a2_2); + phi_v1 = get_bank_or_seq(0, 2, phi_a2_2); phi_a2_3 = arg0; } if ((phi_v1 == 0) && (func_800BB99C(phi_a2_3, 2, phi_a2_3) == 0)) { @@ -1025,15 +963,15 @@ void func_800BBEF0(u32 player, u32 seqId, s32 loadAsync) { #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800B9A90(?, ?, s8); // extern +s32 get_bank_or_seq(?, ?, s8); // extern s32 func_800BB864(s32, ?, void *); // extern s32 func_800BB99C(s8, ?); // extern s32 func_800BBA50(s8, ?, void *); // extern -s32 func_800BBBA0(s8, s32 *, s32 *); // extern +s32 get_missing_bank(s8, s32 *, s32 *); // extern s32 func_800BBCD0(s8, void *, s32 *); // extern -void func_800BEF2C(void *); // extern -void func_800C11B0(s32); // extern -extern u32 D_803B1510; +void sequence_player_disable(void *); // extern +void init_sequence_player(s32); // extern +extern u32 gSequencePlayers; extern s32 D_803B706C; extern u16 D_803B707C; @@ -1059,14 +997,14 @@ void func_800BBF44(s32 arg0, u32 arg1, s32 arg2) { if (temp_v0->unk8 == 0) { phi_s1 = temp_v0->unk4; } - temp_s0 = (arg0 * 0x148) + &D_803B1510; - func_800BEF2C(temp_s0); + temp_s0 = (arg0 * 0x148) + &gSequencePlayers; + sequence_player_disable(temp_s0); temp_a1 = &sp28; temp_a2 = &sp2C; if (arg2 != 0) { sp2C = 0; sp28 = 0; - temp_v0_2 = func_800BBBA0(phi_s1, temp_a1, temp_a2); + temp_v0_2 = get_missing_bank(phi_s1, temp_a1, temp_a2); temp_a0 = temp_v0_2; if (sp2C == 1) { sp24 = temp_v0_2; @@ -1085,7 +1023,7 @@ void func_800BBF44(s32 arg0, u32 arg1, s32 arg2) { if (func_800BBCD0(phi_s1, temp_s0 + 5, temp_a2) != 0) { block_10: temp_s0->unk4 = phi_s1; - temp_v0_3 = func_800B9A90(0, 2, phi_s1); + temp_v0_3 = get_bank_or_seq(0, 2, phi_s1); phi_v1 = temp_v0_3; if (temp_v0_3 == 0) { if ((temp_s0->unk0 * 8) >= 0) { @@ -1102,7 +1040,7 @@ block_10: } else { block_16: sp3C = phi_v1; - func_800C11B0(arg0); + init_sequence_player(arg0); temp_s0->unk88 = 0; temp_s0->unkE = 0; temp_s0->unk0 = temp_s0->unk0 | 0x80; @@ -1117,35 +1055,70 @@ block_16: GLOBAL_ASM("asm/non_matchings/audio/load/func_800BBF44.s") #endif -// L800BC170 is in a delay slot -// m2c may be inaccurate. #ifdef MIPS_TO_C +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +? audio_dma_copy_immediate(? *, s32 *, u32, void **); /* extern */ +? func_800B90F0(s32); /* extern */ +? func_800BA00C(); /* extern */ +? func_800BB43C(s32 *, ? *); /* extern */ +? init_sequence_players(); /* extern */ +? func_800CBF48(u32 *); /* extern */ +extern s8 D_803B0500; +extern s8 D_803B0501; +extern void *D_803B6738; +extern s32 *D_803B706C; +extern s32 *D_803B7070; +extern s32 *D_803B7074; +extern s32 *gAlBankSets; +extern s16 D_803B707C; +extern void *gCtlEntries; +extern s8 gAudioLibSoundMode; +extern s32 D_803B70B8; +extern s32 D_803B70C0; +extern s32 D_803B70C4; +extern s32 D_803B70D4; +extern ? D_803B70D8; +extern f32 D_803B7178; +extern s32 D_803B717C; +extern void *D_803B7180; +extern ? D_803B718C; +extern ? D_803B7192; +extern ? D_803B71A0; +extern ? D_803B71B0; +extern ? _audio_banksSegmentRomStart; +extern ? _audio_tablesSegmentRomStart; +extern ? _instrument_setsSegmentRomStart; +extern ? _sequencesSegmentRomStart; +extern s32 osTvType; +static s32 D_800EA5D0 = 0x00048C00; /* const */ +static s32 D_800EA5D4 = 0x00002600; /* const */ +static u32 D_800EA5D8 = 0; /* const */ +static s32 D_800EA5DC = 0; /* const */ + void audio_init(void) { s32 sp8C; s32 sp60; - s32 **sp3C; + void **sp3C; ? *var_v0; - ? *var_v0_2; ? *var_v0_3; s16 temp_s3; s16 temp_t1; - s32 **var_a2; s32 *temp_v0_2; s32 *temp_v0_3; s32 *temp_v0_4; s32 *temp_v0_5; - s32 temp_a1; - s32 temp_a1_2; - s32 temp_a1_3; - s32 temp_s0; - s32 temp_s0_2; s32 temp_t7; s32 temp_v0; s32 var_s0_2; s32 var_s1; s32 var_v1; s32 var_v1_2; + u32 *var_v0_2; + u32 temp_a1; + u32 temp_a1_2; + u32 temp_a1_3; u32 var_s0; + void **var_a2; void *temp_t3; void *temp_t7_2; @@ -1172,34 +1145,34 @@ void audio_init(void) { temp_v0 = osTvType; switch (temp_v0) { /* irregular */ case 0: - D_803B7178 = D_800F2EA0; - D_803B717C = 0x32; + D_803B7178 = 20.03042f; + D_803B717C = 0x00000032; break; case 2: - D_803B7178 = D_800F2EA4; - D_803B717C = 0x3C; + D_803B7178 = 16.546f; + D_803B717C = 0x0000003C; break; default: case 1: - D_803B7178 = D_800F2EA8; - D_803B717C = 0x3C; + D_803B7178 = 16.713f; + D_803B717C = 0x0000003C; break; } func_800CBF48(&gGfxSPTaskOutputBufferSize); var_v0_3 = &D_803B718C; do { var_v0_3 += 2; - var_v0_3->unk-2 = 0xA0; + var_v0_3->unk-2 = 0x00A0; } while ((u32) var_v0_3 < (u32) &D_803B7192); D_803B70B8 = 0; D_803B70C0 = 0; D_803B70C4 = 0; - D_803B70B6 = 0; + gAudioLibSoundMode = 0; D_803B70D4 = 0; D_803B70D8.unk34 = 0; D_803B70D8.unk84 = 0; osCreateMesgQueue(&D_803B6720, &D_803B6738, 1); - osCreateMesgQueue(&gCurrAudioFrameDmaQueue, &gCurrAudioFrameDmaMesgBufs, 0x40); + osCreateMesgQueue(&gCurrAudioFrameDmaQueue, gCurrAudioFrameDmaMesgBufs, 0x00000040); gCurrAudioFrameDmaCount = 0; gSampleDmaNumListItems = 0; func_800B90F0(D_800EA5D4); @@ -1207,8 +1180,8 @@ void audio_init(void) { do { sp3C = var_a2; var_v1 = 0; - *var_a2 = soundAlloc(&D_803AFBD8, 0xA00, var_a2); -loop_16: + *var_a2 = soundAlloc(&gAudioInitPool, 0x00000A00U); +loop_18: *(*var_a2 + var_v1) = 0; (*var_a2 + var_v1)->unk2 = 0; (*var_a2 + var_v1)->unk4 = 0; @@ -1216,7 +1189,7 @@ loop_16: var_v1 += 8; temp_t7_2->unk6 = 0; if (var_v1 != 0xA00) { - goto loop_16; + goto loop_18; } var_a2 += 4; } while ((u32) var_a2 < (u32) &D_803B718C); @@ -1224,52 +1197,50 @@ loop_16: D_803B0500 = 1; func_800BA00C(); D_803B706C = &sp60; - audio_dma_copy_immediate(&_sequencesSegmentRomStart, &sp60, 0x10); + audio_dma_copy_immediate(&_sequencesSegmentRomStart, &sp60, 0x00000010U); temp_t1 = D_803B706C->unk2; temp_a1 = (((temp_t1 & 0xFFFF) * 8) + 0x13) & ~0xF; D_803B707C = temp_t1; - temp_v0_2 = soundAlloc(&D_803AFBD8, temp_a1); + temp_v0_2 = soundAlloc(&gAudioInitPool, temp_a1); D_803B706C = temp_v0_2; audio_dma_copy_immediate(&_sequencesSegmentRomStart, temp_v0_2, temp_a1); func_800BB43C(D_803B706C, &_sequencesSegmentRomStart); D_803B7070 = &sp60; - audio_dma_copy_immediate(&_audio_banksSegmentRomStart, &sp60, 0x10); + audio_dma_copy_immediate(&_audio_banksSegmentRomStart, &sp60, 0x00000010U); temp_s3 = D_803B7070->unk2; temp_a1_2 = ((temp_s3 * 8) + 0x13) & ~0xF; - temp_s0 = temp_a1_2; - temp_v0_3 = soundAlloc(&D_803AFBD8, temp_a1_2); + temp_v0_3 = soundAlloc(&gAudioInitPool, temp_a1_2); D_803B7070 = temp_v0_3; - audio_dma_copy_immediate(&_audio_banksSegmentRomStart, temp_v0_3, temp_s0); + audio_dma_copy_immediate(&_audio_banksSegmentRomStart, temp_v0_3, temp_a1_2); func_800BB43C(D_803B7070, &_audio_banksSegmentRomStart); - D_803B7080 = soundAlloc(&D_803AFBD8, temp_s3 * 0xC); + gCtlEntries = soundAlloc(&gAudioInitPool, temp_s3 * 0xC); var_v1_2 = 0; if (temp_s3 > 0) { var_s1 = 0; var_s0_2 = 0; do { sp8C = var_v1_2; - audio_dma_copy_immediate((D_803B7070 + var_s1)->unk4, &sp60, 0x10, &D_803B7080); - (D_803B7080 + var_s0_2)->unk1 = (s8) sp60; + audio_dma_copy_immediate((D_803B7070 + var_s1)->unk4, &sp60, 0x00000010U, &gCtlEntries); + (gCtlEntries + var_s0_2)->unk1 = (s8) sp60; var_v1_2 = sp8C + 1; - temp_t3 = D_803B7080 + var_s0_2; + temp_t3 = gCtlEntries + var_s0_2; var_s0_2 += 0xC; var_s1 += 8; temp_t3->unk2 = (s8) sp64; } while (var_v1_2 != temp_s3); } D_803B7074 = &sp60; - audio_dma_copy_immediate(&_audio_tablesSegmentRomStart, &sp60, 0x10, &D_803B7080); + audio_dma_copy_immediate(&_audio_tablesSegmentRomStart, &sp60, 0x00000010U, &gCtlEntries); temp_a1_3 = ((D_803B7074->unk2 * 8) + 0x13) & ~0xF; - temp_s0_2 = temp_a1_3; - temp_v0_4 = soundAlloc(&D_803AFBD8, temp_a1_3); + temp_v0_4 = soundAlloc(&gAudioInitPool, temp_a1_3); D_803B7074 = temp_v0_4; - audio_dma_copy_immediate(&_audio_tablesSegmentRomStart, temp_v0_4, temp_s0_2); + audio_dma_copy_immediate(&_audio_tablesSegmentRomStart, temp_v0_4, temp_a1_3); func_800BB43C(D_803B7074, &_audio_tablesSegmentRomStart); - temp_v0_5 = soundAlloc(&D_803AFBD8, 0x100); - D_803B7078 = temp_v0_5; - audio_dma_copy_immediate(&_instrument_setsSegmentRomStart, temp_v0_5, 0x100); - func_800B907C(&D_803B01B8, soundAlloc(&D_803AFBD8, D_800EA5D8), D_800EA5D8); - func_800C125C(); + temp_v0_5 = soundAlloc(&gAudioInitPool, 0x00000100U); + gAlBankSets = temp_v0_5; + audio_dma_copy_immediate(&_instrument_setsSegmentRomStart, temp_v0_5, 0x00000100U); + sound_alloc_pool_init(&gUnkPool1.pool, soundAlloc(&gAudioInitPool, D_800EA5D8), D_800EA5D8); + init_sequence_players(); D_800EA5DC = 0x76557364; } #else diff --git a/src/audio/load.h b/src/audio/load.h index 58b84fb7a..ee5e1adeb 100644 --- a/src/audio/load.h +++ b/src/audio/load.h @@ -2,17 +2,37 @@ #define AUDIO_LOAD_H #include <PR/ultratypes.h> -#include "internal.h" +#include "audio/internal.h" #define AUDIO_FRAME_DMA_QUEUE_SIZE 0x40 #define PRELOAD_BANKS 2 #define PRELOAD_SEQUENCE 1 -void func_800BAAF8(uintptr_t, void*, size_t, OSMesgQueue*, OSIoMesg*); -void func_800BAB58(uintptr_t*, u8**, ssize_t*, OSMesgQueue*, OSIoMesg*); -void func_800BAC04(); +#define IS_SEQUENCE_CHANNEL_VALID(ptr) ((uintptr_t)(ptr) != (uintptr_t)&gSequenceChannelNone) + +void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes); +void audio_dma_copy_async(uintptr_t, void*, size_t, OSMesgQueue*, OSIoMesg*); +void audio_dma_partial_copy_async(uintptr_t*, u8**, ssize_t*, OSMesgQueue*, OSIoMesg*); +void decrease_sample_dma_ttls(); void func_800BB030(s32); s32 func_800BB304(struct AudioBankSample*); +s32 func_800BB388(s32 bankId, s32 instId, s32 arg2); +void patch_sound(struct AudioBankSound *sound, u8 *memBase, u8 *offsetBase); +void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums); + +extern struct Note *gNotes; +extern struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; +extern struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS]; +extern struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS]; +extern struct SequenceChannel gSequenceChannelNone; +extern struct AudioListItem gLayerFreeList; +extern struct NotePool gNoteFreeLists; +extern u8 *gAlBankSets; +extern struct CtlEntry *gCtlEntries; +extern struct AudioBufferParametersEU gAudioBufferParameters; +extern s32 gMaxSimultaneousNotes; +extern s8 gAudioUpdatesPerFrame; // = 4 +extern s8 gAudioLibSoundMode; #endif // AUDIO_LOAD_H diff --git a/src/audio/playback.c b/src/audio/playback.c index b40c73600..44d9833fc 100644 --- a/src/audio/playback.c +++ b/src/audio/playback.c @@ -1,1231 +1,778 @@ #include <ultra64.h> #include <macros.h> -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern f32 D_800F2EB0; -extern f32 D_800F2EB4; -extern s8 D_803B70B6; -extern f32 gDefaultPanVolume; -extern u16 gHeadsetPanQuantization; -extern f32 gHeadsetPanVolume; -extern f32 gStereoPanVolume; - -void func_800BC5D0(void *arg0, f32 arg1, s32 arg2, u8 arg3) { - f32 temp_f14; - f32 temp_f2; - s32 temp_a1; - s32 temp_a3; - s32 temp_t4; - s32 temp_t8; - s8 temp_t3; - s8 temp_v1; - u8 temp_t1; - u8 temp_t8_2; - void *temp_v0; - void *temp_v0_2; - s32 phi_a1; - s32 phi_a0; - s32 phi_a1_2; - f32 phi_f12; - f32 phi_f12_2; - f32 phi_f0; - void *phi_v0; - f32 phi_f2; - - temp_t8 = arg2 & 0x7F; - phi_f12 = arg1; - if ((arg0->unkB0 & 0x2000000) && (temp_a1 = temp_t8 >> 3, temp_v0 = arg0 + 0xB0, phi_a1 = temp_a1, phi_v0 = temp_v0, (D_803B70B6 == 1))) { - if (temp_a1 >= 0x10) { - phi_a1 = 0xF; +#include "audio/internal.h" +#include "audio/playback.h" +#include "audio/load.h" +#include "audio/heap.h" +#include "audio/external.h" +#include "audio/effects.h" +#include "audio/data.h" +#include "audio/seqplayer.h" + +void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbVol) { + struct NoteSubEu *sub = ¬e->noteSubEu; + f32 volRight, volLeft; + u8 strongRight; + u8 strongLeft; + s32 smallPanIndex; + u16 unkMask = ~0x80; + + pan &= unkMask; + + if (note->noteSubEu.stereoHeadsetEffects && gAudioLibSoundMode == SOUND_MODE_HEADSET) { + smallPanIndex = pan >> 3; + if (smallPanIndex >= ARRAY_COUNT(gHeadsetPanQuantization)) { + smallPanIndex = ARRAY_COUNT(gHeadsetPanQuantization) - 1; } - temp_a3 = phi_a1 * 2; - temp_v0->unk4 = *(&gHeadsetPanQuantization + temp_a3); - temp_t8_2 = temp_v0->unk0 & 0xFFF7; - temp_t1 = temp_t8_2 & 0xFB; - temp_v0->unk0 = temp_t8_2; - temp_v0->unk0 = temp_t1; - temp_v0->unk0 = temp_t1 | 1; - temp_v0->unk3 = *(&gHeadsetPanQuantization + 0x1E + -temp_a3); - phi_f0 = *(&gHeadsetPanVolume + (temp_t8 * 4)); - phi_f2 = *(&gHeadsetPanVolume + 0x1FC + -(temp_t8 * 4)); - } else { - temp_v0_2 = arg0 + 0xB0; - temp_v1 = D_803B70B6; - phi_v0 = temp_v0_2; - if ((temp_v0_2->unk0 & 0x2000000) && (phi_a0 = 0, (temp_v1 == 0))) { - temp_v0_2->unk3 = 0; - temp_v0_2->unk4 = 0; - temp_v0_2->unk0 = temp_v0_2->unk0 & 0xFFFE; - phi_a1_2 = 0; - phi_f0 = *(&gStereoPanVolume + (temp_t8 * 4)); - phi_f2 = *(&gStereoPanVolume + 0x1FC + -(temp_t8 * 4)); - if (temp_t8 < 0x20) { - phi_a1_2 = 1; - } else if (temp_t8 >= 0x61) { - phi_a0 = 1; - } - temp_t3 = ((phi_a0 * 8) & 8) | (temp_v0_2->unk0 & 0xFFF7); - temp_t4 = temp_t3 & 0xFB; - temp_v0_2->unk0 = temp_t3; - temp_v0_2->unk0 = ((phi_a1_2 * 4) & 4) | temp_t4; - } else if (temp_v1 == 3) { - temp_f2 = D_800F2EB0; - phi_f0 = temp_f2; - phi_f2 = temp_f2; - } else { - phi_f0 = *(&gDefaultPanVolume + (temp_t8 * 4)); - phi_f2 = *(&gDefaultPanVolume + 0x1FC + -(temp_t8 * 4)); + + sub->headsetPanLeft = gHeadsetPanQuantization[smallPanIndex]; + sub->headsetPanRight = gHeadsetPanQuantization[ARRAY_COUNT(gHeadsetPanQuantization) - 1 - smallPanIndex]; + sub->stereoStrongRight = FALSE; + sub->stereoStrongLeft = FALSE; + sub->usesHeadsetPanEffects = TRUE; + + volLeft = gHeadsetPanVolume[pan]; + volRight = gHeadsetPanVolume[127 - pan]; + } else if (sub->stereoHeadsetEffects && gAudioLibSoundMode == SOUND_MODE_STEREO) { + strongRight = FALSE; + strongLeft = FALSE; + sub->headsetPanRight = 0; + sub->headsetPanLeft = 0; + + sub->usesHeadsetPanEffects = FALSE; + + volLeft = gStereoPanVolume[pan]; + volRight = gStereoPanVolume[127 - pan]; + if (pan < 0x20) { + strongLeft = TRUE; + } else if (pan > 0x60) { + strongRight = TRUE; } + + sub->stereoStrongRight = strongRight; + sub->stereoStrongLeft = strongLeft; + + } else if (gAudioLibSoundMode == SOUND_MODE_MONO) { + volLeft = 0.707f; + volRight = 0.707f; + } else { + volLeft = gDefaultPanVolume[pan]; + volRight = gDefaultPanVolume[127 - pan]; } - if (arg1 < 0.0f) { - phi_f12 = 0.0f; + + if (velocity < 0.0f) { + stubbed_printf("Audio: setvol: volume minus %f\n", velocity); + velocity = 0.0f; } - phi_f12_2 = phi_f12; - if (phi_f12 > 1.0f) { - phi_f12_2 = 1.0f; + if (velocity > 1.0f) { + stubbed_printf("Audio: setvol: volume overflow %f\n", velocity); + velocity = 1.0f; } - temp_f14 = D_800F2EB4; - phi_v0->unk6 = phi_f12_2 * phi_f0 * temp_f14; - phi_v0->unk8 = phi_f12_2 * phi_f2 * temp_f14; - if (arg3 != phi_v0->unk5) { - phi_v0->unk5 = arg3; - phi_v0->unk0 = phi_v0->unk0 | 0x10; + + sub->targetVolLeft = ((s32) (velocity * volLeft * 4095.999f)); + sub->targetVolRight = ((s32) (velocity * volRight * 4095.999f)); + + //! @bug for the change to UQ0.7, the if statement should also have been changed accordingly + if (sub->reverbVol != reverbVol) { + sub->reverbVol = reverbVol; + sub->envMixerNeedsInit = TRUE; return; } - if ((phi_v0->unk0 * 2) < 0) { - phi_v0->unk0 = phi_v0->unk0 | 0x10; - return; + + if (sub->needsInit) { + sub->envMixerNeedsInit = TRUE; + } else { + sub->envMixerNeedsInit = FALSE; } - phi_v0->unk0 = phi_v0->unk0 & 0xFFEF; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BC5D0.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern f32 D_800F2EB8; -extern f32 D_800F2EBC; -extern f32 D_800F2EC0; - -void func_800BC840(void *arg0, f32 arg1) { - f32 temp_f2; - void *temp_v0; - void *temp_v0_2; - f32 phi_f12; - f32 phi_f0; - - temp_v0 = arg0 + 0xB0; - phi_f12 = arg1; - if (arg1 < 0.0f) { - phi_f12 = 0.0f; +void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput) { + f32 resamplingRate = 0.0f; + struct NoteSubEu *tempSub = ¬e->noteSubEu; + + if (resamplingRateInput < 0.0f) { + stubbed_printf("Audio: setpitch: pitch minus %f\n", resamplingRateInput); + resamplingRateInput = 0.0f; } - if (phi_f12 < 2.0f) { - temp_f2 = D_800F2EB8; - temp_v0_2 = arg0 + 0xB0; - temp_v0_2->unk1 = temp_v0_2->unk1 & 0xFFFE; - if (temp_f2 < phi_f12) { - phi_f0 = temp_f2; + if (resamplingRateInput < 2.0f) { + tempSub->hasTwoAdpcmParts = 0; + + if (1.9999599f < resamplingRateInput) { + resamplingRate = 1.9999599f; } else { - phi_f0 = phi_f12; + resamplingRate = resamplingRateInput; } + } else { - temp_v0->unk1 = temp_v0->unk1 | 1; - if (D_800F2EBC < phi_f12) { - phi_f0 = D_800F2EC0; + tempSub->hasTwoAdpcmParts = 1; + if (2 * 1.9999599f < resamplingRateInput) { + resamplingRate = 1.9999599f; } else { - phi_f0 = phi_f12 * 0.5f; + resamplingRate = resamplingRateInput * 0.5f; } } - arg0->unkBA = phi_f0 * 32768.0f; + note->noteSubEu.resamplingRateFixedPoint = (s32) (resamplingRate * 32768.0f); } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BC840.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void *func_800BC90C(void *arg0, s32 arg1) { - if (arg1 < arg0->unk1) { - return arg0 + 8; - } - if (arg0->unk2 >= arg1) { - return arg0 + 0x10; +struct AudioBankSound *instrument_get_audio_bank_sound(struct Instrument *instrument, s32 semitone) { + struct AudioBankSound *sound; + if (semitone < instrument->normalRangeLo) { + sound = &instrument->lowNotesSound; + } else if (semitone <= instrument->normalRangeHi) { + sound = &instrument->normalNotesSound; + } else { + sound = &instrument->highNotesSound; } - return arg0 + 0x18; + return sound; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BC90C.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern u8 D_803B03C0; -extern s32 D_803B7080; -extern s32 D_803B7198; -s32 func_800BC948(s32 arg0, s32 arg1) { - s32 temp_v1; - void *temp_v0; +struct Instrument *get_instrument_inner(s32 bankId, s32 instId) { + struct Instrument *inst; - if (*(&D_803B03C0 + arg0) < 2) { - D_803B7198 = arg0 + 0x10000000; - return 0; + if (IS_BANK_LOAD_COMPLETE(bankId) == FALSE) { + stubbed_printf("Audio: voiceman: No bank error %d\n", bankId); + gAudioErrorFlags = bankId + 0x10000000; + return NULL; } - temp_v0 = D_803B7080 + (arg0 * 0xC); - if (arg1 >= temp_v0->unk1) { - D_803B7198 = (arg0 << 8) + arg1 + 0x3000000; - return 0; + + if (instId >= gCtlEntries[bankId].numInstruments) { + stubbed_printf("Audio: voiceman: progNo. overflow %d,%d\n", + instId, gCtlEntries[bankId].numInstruments); + gAudioErrorFlags = ((bankId << 8) + instId) + 0x3000000; + return NULL; } - temp_v1 = *(temp_v0->unk4 + (arg1 * 4)); - if (temp_v1 == 0) { - D_803B7198 = (arg0 << 8) + arg1 + 0x1000000; - return temp_v1; + + inst = gCtlEntries[bankId].instruments[instId]; + if (inst == NULL) { + stubbed_printf("Audio: voiceman: progNo. undefined %d,%d\n", bankId, instId); + gAudioErrorFlags = ((bankId << 8) + instId) + 0x1000000; + return inst; } - return temp_v1; + return inst; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BC948.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern u8 D_803B03C0; -extern s32 D_803B7080; -extern s32 D_803B7198; -s32 func_800BC9F8(s32 arg0, s32 arg1) { - s32 temp_a2; - u32 temp_v1; - void *temp_v0; +struct Drum *get_drum(s32 bankId, s32 drumId) { + struct Drum *drum; - if (*(&D_803B03C0 + arg0) < 2) { - D_803B7198 = arg0 + 0x10000000; - return 0; + if (IS_BANK_LOAD_COMPLETE(bankId) == FALSE) { + stubbed_printf("Audio: voiceman: No bank error %d\n", bankId); + gAudioErrorFlags = bankId + 0x10000000; + return NULL; } - temp_v0 = D_803B7080 + (arg0 * 0xC); - if (arg1 >= temp_v0->unk2) { - D_803B7198 = (arg0 << 8) + arg1 + 0x4000000; - return 0; + + if (drumId >= gCtlEntries[bankId].numDrums) { + stubbed_printf("Audio: voiceman: Percussion Overflow %d,%d\n", + drumId, gCtlEntries[bankId].numDrums); + gAudioErrorFlags = ((bankId << 8) + drumId) + 0x4000000; + return NULL; } - temp_v1 = temp_v0->unk8; - if (temp_v1 < 0x80000000) { - return 0; + + if ((uintptr_t) gCtlEntries[bankId].drums < 0x80000000U) { + stubbed_printf("Audio: voiceman: Percussion table pointer (bank %d) is irregular.\n"); + return NULL; } - temp_a2 = *(temp_v1 + (arg1 * 4)); - if (temp_a2 == 0) { - D_803B7198 = (arg0 << 8) + arg1 + 0x5000000; + + drum = gCtlEntries[bankId].drums[drumId]; + if (drum == NULL) { + stubbed_printf("Audio: voiceman: Percpointer NULL %d,%d\n", bankId, drumId); + gAudioErrorFlags = ((bankId << 8) + drumId) + 0x5000000; } - return temp_a2; + // Don't know where these actually belong, putting them here because why not + // Really, we just need these so the format strings could put into the .data section + stubbed_printf("--4 %x\n", gAudioErrorFlags); + stubbed_printf("Stoped Voice\n"); + return drum; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BC9F8.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BE5BC(void *, s32, void *, void *); // extern -extern NoteSub gDefaultNoteSub; - -void func_800BCAB4(void *arg0) { - s32 temp_a1; - void *temp_a0; - void *temp_a2; - void *temp_a3; - void *temp_v0; - - temp_v0 = arg0->unk44; - temp_a3 = arg0; - if (temp_v0->unk18 == 0) { - temp_a0 = arg0 + 0x58; - temp_a2 = temp_a3 + 0x34; - temp_a1 = temp_v0->unk4C->unk80; - arg0 = temp_a3; - func_800BE5BC(temp_a0, temp_a1, temp_a2, temp_a3); +void note_init(struct Note *note) { + if (note->parentLayer->adsr.releaseRate == 0) { + adsr_init(¬e->adsr, note->parentLayer->seqChannel->adsr.envelope, ¬e->adsrVolScale); } else { - arg0 = temp_a3; - func_800BE5BC(temp_a3 + 0x58, temp_v0->unk1C, temp_a3 + 0x34, temp_a3); + adsr_init(¬e->adsr, note->parentLayer->adsr.envelope, ¬e->adsrVolScale); } - arg0->unk59 = 1; - arg0->unkB0 = gDefaultNoteSub.unk0; - arg0->unkB4 = gDefaultNoteSub.unk4; - arg0->unkB8 = gDefaultNoteSub.unk8; - arg0->unkBC = gDefaultNoteSub.unkC; + note->adsr.state = ADSR_STATE_INITIAL; + note->noteSubEu = gDefaultNoteSub; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BCAB4.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BC5D0(?, ?, ?); // extern -void func_800BCB48(void *arg0) { - if (((arg0->unkB0 * 2) >> 0x1F) == 1) { - arg0->unkB0 = arg0->unkB0 & 0xFFBF; +void note_disable(struct Note *note) { + if (note->noteSubEu.needsInit == TRUE) { + note->noteSubEu.needsInit = FALSE; } else { - func_800BC5D0(0, 0x40, 0); + note_set_vel_pan_reverb(note, 0, 0x40, 0); } - arg0->unk30 = 0; - arg0->unkB0 = arg0->unkB0 & 0xFF7F; - arg0->unk44 = -1; - arg0->unk40 = -1; - arg0->unkB0 = arg0->unkB0 & 0xFFDF; + note->priority = NOTE_PRIORITY_DISABLED; + note->parentLayer = NO_LAYER; + note->prevParentLayer = NO_LAYER; + note->noteSubEu.enabled = FALSE; + note->noteSubEu.finished = FALSE; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BCB48.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BC5D0(void *, f32, u8, u8); // extern -void func_800BC840(void *, f32, u8, u8); // extern -void func_800BCB48(void *, void *); // extern -void func_800BD140(u32, u32); // extern -void func_800BD6B4(s32, void *); // extern -void func_800BD6F4(void *); // extern -void func_800BD7C0(void *, void *); // extern -void func_800BE468(void *); // extern -void func_800BE4D4(void *); // extern -f32 func_800BE5E0(void *); // extern -void func_800BEBA4(void *, u32); // extern -void func_800BF004(s32, void *); // extern -extern s32 D_803B1508; -extern s32 gMaxSimultaneousNotes; - -void func_800BCBC4(void) { - u8 sp4B; - u8 sp49; - f32 temp_f22; - s32 *temp_s3; - s32 *temp_s3_2; - s32 *temp_v0; - s32 temp_s5; - s32 temp_v1; - s32 temp_v1_2; - s32 temp_v1_3; - u32 temp_a1; - u8 *temp_s1; - u8 *temp_s1_2; - u8 temp_v0_2; - void *temp_a0; - void *temp_a0_2; - void *temp_a1_2; - void *temp_a1_3; - void *temp_s0; - void *temp_v0_3; - s32 phi_s5; - u8 phi_v0; - u8 *phi_s1; - u8 phi_a3; - u8 phi_a2; - f32 phi_f0; - f32 phi_f20; - s32 phi_s2; - s32 *phi_s3; - s32 phi_v0_2; - s32 phi_v1; - - temp_v1 = gMaxSimultaneousNotes; - phi_v1 = temp_v1; - if (temp_v1 > 0) { - phi_s5 = 0; - do { - temp_s0 = phi_s5 + D_803B1508; - temp_s1 = temp_s0 + 0x30; - phi_s1 = temp_s1; - if (temp_s0->unk44 != -1) { - temp_s1_2 = temp_s0 + 0x30; - temp_a1 = temp_s1_2->unk14; - phi_s1 = temp_s1_2; - if (temp_a1 < 0x7FFFFFFF) { - phi_v0_2 = phi_v1 * 3; - } else if (((temp_a1->unk0 >> 0x1F) != 0) || (temp_s1_2->unk0 < 2)) { - temp_a0 = temp_a1->unk4C; - temp_v0 = temp_a0->unk44; - if (temp_v0 == 0) { - func_800BEBA4(temp_a0, temp_a1); - temp_s1_2->unk0 = 1; - temp_v1_2 = gMaxSimultaneousNotes; - phi_v0_2 = temp_v1_2 * 3; - phi_v1 = temp_v1_2; - } else { - if (((*temp_v0 * 4) >= 0) || ((temp_a0->unk3 & 0xC0) == 0)) { - phi_v0 = temp_s1_2->unk0; - } else { - goto block_12; - } - goto block_15; - } - } else { -block_12: - func_800BD140(temp_a1, temp_a1); - func_800BD6F4(temp_s0); - func_800BD6B4(temp_s0->unkC + 0x10, temp_s0); - temp_s1_2->unk0 = 1; - phi_v0 = 1 & 0xFF; - goto block_15; +void process_notes(void) { + f32 scale; + f32 frequency; + f32 velocity; + struct Note *note; + struct NotePlaybackState *playbackState; + struct NoteSubEu *noteSubEu; + UNUSED u8 pad[12]; + u8 reverbVol; + UNUSED u8 pad3; + u8 pan; + u8 bookOffset; + struct NoteAttributes *attributes; + s32 i; + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + note = &gNotes[i]; + playbackState = (struct NotePlaybackState *) ¬e->priority; + if (note->parentLayer != NO_LAYER) { +#ifndef NO_SEGMENTED_MEMORY + if ((uintptr_t) playbackState->parentLayer < 0x7fffffffU) { + continue; + } +#endif + if (!playbackState->parentLayer->enabled && playbackState->priority >= NOTE_PRIORITY_MIN) { + goto c; + } else if (playbackState->parentLayer->seqChannel->seqPlayer == NULL) { + eu_stubbed_printf_0("CAUTION:SUB IS SEPARATED FROM GROUP"); + sequence_channel_disable(playbackState->parentLayer->seqChannel); + playbackState->priority = NOTE_PRIORITY_STOPPING; + continue; + } else if (playbackState->parentLayer->seqChannel->seqPlayer->muted) { + if ((playbackState->parentLayer->seqChannel->muteBehavior + & (MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES))) { + goto c; } - } else { - temp_v0_2 = *temp_s1; - phi_v0 = temp_v0_2; - if (temp_v0_2 >= 2) { - phi_v0_2 = phi_v1 * 3; - } else { -block_15: - if (phi_v0 != 0) { - temp_s3 = temp_s0 + 0xB0; - phi_s3 = temp_s3; - if ((phi_v0 == 1) || ((*temp_s3 * 4) < 0)) { - temp_s3_2 = temp_s0 + 0xB0; - phi_s3 = temp_s3_2; - if ((phi_s1->unk29 == 0) || ((*temp_s3_2 * 4) < 0)) { - if (phi_s1->unk18 != -1) { - func_800BCB48(temp_s0); - temp_a1_2 = phi_s1->unk18; - if (temp_a1_2->unk4C != 0) { - func_800BD7C0(temp_s0, temp_a1_2); - func_800BE4D4(temp_s0); - func_800BD6F4(temp_s0); - func_800BF004(temp_s0->unkC + 0x30, temp_s0); - phi_s1->unk18 = -1; - phi_s3 = temp_s0 + 0xB0; - goto block_27; - } - func_800BCB48(temp_s0, temp_a1_2); - func_800BD6F4(temp_s0); - func_800BF004(temp_s0->unkC, temp_s0); - phi_s1->unk18 = -1; - } else { - func_800BCB48(temp_s0); - func_800BD6F4(temp_s0); - func_800BF004(temp_s0->unkC, temp_s0); - } - } else { - goto block_27; - } - } else if (phi_s1->unk29 == 0) { - func_800BCB48(temp_s0); - func_800BD6F4(temp_s0); - func_800BF004(temp_s0->unkC, temp_s0); + } + goto d; + c: + seq_channel_layer_note_release(playbackState->parentLayer); + audio_list_remove(¬e->listItem); + audio_list_push_front(¬e->listItem.pool->decaying, ¬e->listItem); + playbackState->priority = NOTE_PRIORITY_STOPPING; + } else if (playbackState->priority >= NOTE_PRIORITY_MIN) { + continue; + } + d: + if (playbackState->priority != NOTE_PRIORITY_DISABLED) { + noteSubEu = ¬e->noteSubEu; + if (playbackState->priority == NOTE_PRIORITY_STOPPING || noteSubEu->finished) { + if (playbackState->adsr.state == ADSR_STATE_DISABLED || noteSubEu->finished) { + if(playbackState && playbackState){} + if (playbackState->wantedParentLayer != NO_LAYER) { + note_disable(note); + if (playbackState->wantedParentLayer->seqChannel != NULL) { + note_init_for_layer(note, playbackState->wantedParentLayer); + note_vibrato_init(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->active, ¬e->listItem); + playbackState->wantedParentLayer = NO_LAYER; + // don't skip } else { -block_27: - temp_f22 = func_800BE5E0(phi_s1 + 0x28); - func_800BE468(temp_s0); - temp_v0_3 = phi_s1 + 0x1C; - if (phi_s1->unk0 == 1) { - phi_a3 = temp_v0_3->unk0; - phi_a2 = temp_v0_3->unk1; - phi_f0 = temp_v0_3->unk4; - phi_f20 = temp_v0_3->unk8; - phi_s2 = ((phi_s3->unk0 << 0xB) >> 0x1D) & 0xFF; - } else { - temp_a1_3 = phi_s1->unk14; - temp_a0_2 = temp_a1_3->unk4C; - phi_a3 = temp_a0_2->unk4; - phi_a2 = temp_a1_3->unk6; - phi_f0 = temp_a1_3->unk30; - phi_f20 = temp_a1_3->unk2C; - phi_s2 = temp_a0_2->unk8 & 7; - } - sp4B = phi_a3; - sp49 = phi_a2; - func_800BC840(temp_s0, phi_f0 * (phi_s1->unkC * phi_s1->unk8), phi_a2, phi_a3); - func_800BC5D0(temp_s0, phi_f20 * temp_f22, phi_a2, phi_a3); - phi_s3->unk1 = ((phi_s2 * 4) & 0x1C) | (phi_s3->unk1 & 0xFFE3); + eu_stubbed_printf_0("Error:Wait Track disappear\n"); + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->disabled, ¬e->listItem); + playbackState->wantedParentLayer = NO_LAYER; + goto skip; } + } else { + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->disabled, ¬e->listItem); + goto skip; } - temp_v1_3 = gMaxSimultaneousNotes; - phi_v0_2 = temp_v1_3 * 3; - phi_v1 = temp_v1_3; } + } else if (playbackState->adsr.state == ADSR_STATE_DISABLED) { + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->disabled, ¬e->listItem); + goto skip; } - temp_s5 = phi_s5 + 0xC0; - phi_s5 = temp_s5; - } while (temp_s5 < (phi_v0_2 << 6)); + + scale = adsr_update(&playbackState->adsr); + note_vibrato_update(note); + attributes = &playbackState->attributes; + if (playbackState->priority == NOTE_PRIORITY_STOPPING) { + frequency = attributes->freqScale; + velocity = attributes->velocity; + pan = attributes->pan; + reverbVol = attributes->reverbVol; + if (1) {} + bookOffset = noteSubEu->bookOffset; + } else { + frequency = playbackState->parentLayer->noteFreqScale; + velocity = playbackState->parentLayer->noteVelocity; + pan = playbackState->parentLayer->notePan; + reverbVol = playbackState->parentLayer->seqChannel->reverbVol; + bookOffset = playbackState->parentLayer->seqChannel->bookOffset & 0x7; + } + + frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale; + velocity = velocity * scale; + note_set_resampling_rate(note, frequency); + note_set_vel_pan_reverb(note, velocity, pan, reverbVol); + noteSubEu->bookOffset = bookOffset; + skip:; + } } } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BCBC4.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD6B4(s32, void *); // extern -void func_800BD6F4(void *, void *, s32, s32); // extern -extern f32 D_803B70A0; -extern f32 D_803B70A4; - -void func_800BCF44(void *arg0, s32 arg1) { - void *sp1C; - f32 temp_f16; - f32 temp_f18; - s32 temp_t6; - s32 temp_v0_2; - u8 temp_t3; - u8 temp_v0_4; - void *temp_v0; - void *temp_v0_3; - void *temp_v1; - f32 phi_f18; - f32 phi_f16; - - if ((arg0 != -1) && (temp_v0 = arg0->unk40, (temp_v0 != 0))) { - if (arg0 == temp_v0->unk48) { - temp_v0->unk48 = -1; - } - temp_v0_2 = temp_v0->unk44; - if (arg0 != temp_v0_2) { - if ((temp_v0_2 == -1) && (temp_v0->unk48 == -1) && (arg0 == temp_v0->unk40) && (arg1 != 6)) { - temp_v0->unk58 = temp_v0->unk58 | 0x10; - temp_v0->unk68 = D_803B70A0; - return; - } - // Duplicate return node #25. Try simplifying control flow for better match - return; +void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLayer, s32 target) { + struct Note *note; + struct NoteAttributes *attributes; + + if ((seqLayer == NO_LAYER) || (seqLayer->note == NULL)) { + return; + } + + note = seqLayer->note; + attributes = ¬e->attributes; + + if (note->wantedParentLayer == seqLayer) { + note->wantedParentLayer = NO_LAYER; + } + + if (note->parentLayer != seqLayer) { + if (note->parentLayer == NO_LAYER && note->wantedParentLayer == NO_LAYER && + note->prevParentLayer == seqLayer && target != ADSR_STATE_DECAY) { + // Just guessing that this printf goes here... it's hard to parse. + eu_stubbed_printf_0("Slow Release Batting\n"); + note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; + note->adsr.action |= ADSR_ACTION_RELEASE; } - arg0->unk2 = 0; - if (temp_v0->unk59 != 6) { - temp_v0_3 = temp_v0 + 0x4C; - temp_v0_3->unk4 = arg0->unk30; - temp_v0_3->unk8 = arg0->unk2C; - temp_v0_3->unk1 = arg0->unk6; - temp_v1 = arg0->unk4C; - if (temp_v1 != 0) { - temp_v0_3->unk0 = temp_v1->unk4; + } else { + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + if (note->adsr.state != ADSR_STATE_DECAY) { + attributes->freqScale = seqLayer->noteFreqScale; + attributes->velocity = seqLayer->noteVelocity; + attributes->pan = seqLayer->notePan; + if (seqLayer->seqChannel != NULL) { + attributes->reverbVol = seqLayer->seqChannel->reverbVol; } - temp_t6 = temp_v0->unk44; - temp_v0->unk30 = 1; - temp_v0->unk44 = -1; - temp_v0->unk40 = temp_t6; - if (arg1 == 7) { - temp_v0->unk58 = temp_v0->unk58 | 0x10; - temp_v0->unk68 = D_803B70A0; + note->priority = NOTE_PRIORITY_STOPPING; + note->prevParentLayer = note->parentLayer; + note->parentLayer = NO_LAYER; + if (target == ADSR_STATE_RELEASE) { + note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; + note->adsr.action |= ADSR_ACTION_RELEASE; } else { - temp_v0->unk58 = temp_v0->unk58 | 0x20; - temp_v0_4 = arg0->unk18; - if (temp_v0_4 == 0) { - temp_t3 = arg0->unk4C->unk7C; - temp_f18 = temp_t3; - phi_f18 = temp_f18; - if (temp_t3 < 0) { - phi_f18 = temp_f18 + 4294967296.0f; - } - temp_v0->unk68 = phi_f18 * D_803B70A4; + note->adsr.action |= ADSR_ACTION_DECAY; + if (seqLayer->adsr.releaseRate == 0) { + note->adsr.fadeOutVel = seqLayer->seqChannel->adsr.releaseRate * gAudioBufferParameters.unkUpdatesPerFrameScaled; } else { - temp_f16 = temp_v0_4; - phi_f16 = temp_f16; - if (temp_v0_4 < 0) { - phi_f16 = temp_f16 + 4294967296.0f; - } - temp_v0->unk68 = phi_f16 * D_803B70A4; + note->adsr.fadeOutVel = seqLayer->adsr.releaseRate * gAudioBufferParameters.unkUpdatesPerFrameScaled; } - temp_v0->unk60 = arg0->unk4C->unk7D * temp_v0->unk6C * 0.00390625f; + note->adsr.sustain = (FLOAT_CAST(seqLayer->seqChannel->adsr.sustain) * note->adsr.current) / 256.0f; } } - if (arg1 == 6) { - sp1C = temp_v0; - func_800BD6F4(temp_v0, temp_v0, -1, arg1); - func_800BD6B4(temp_v0->unkC + 0x10, temp_v0); + + if (target == ADSR_STATE_DECAY) { + audio_list_remove(¬e->listItem); + audio_list_push_front(¬e->listItem.pool->decaying, ¬e->listItem); } - // Duplicate return node #25. Try simplifying control flow for better match } } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BCF44.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BCF44(?); // extern +void seq_channel_layer_note_decay(struct SequenceChannelLayer *seqLayer) { + seq_channel_layer_decay_release_internal(seqLayer, ADSR_STATE_DECAY); +} -void func_800BD120(void) { - func_800BCF44(6); +void seq_channel_layer_note_release(struct SequenceChannelLayer *seqLayer) { + seq_channel_layer_decay_release_internal(seqLayer, ADSR_STATE_RELEASE); } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD120.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BCF44(?); // extern +const u8 D_800E98F4[4] = { 0x40, 0x20, 0x10, 0x08 }; -void func_800BD140(void) { - func_800BCF44(7); -} -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD140.s") -#endif +s32 build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer, s32 waveId) { + f32 freqScale; + f32 ratio; + u8 sampleCountIndex; -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern f32 D_800F2EC4; -extern f32 D_800F2EC8; -extern f32 D_800F2ECC; -extern f32 D_800F2ED0; -extern s16 gUnknownWave7; - -s8 func_800BD160(void *arg0, void *arg1, s32 arg2) { - f32 temp_f12; - f32 temp_f2; - f32 phi_f0; - f32 phi_f0_2; - s8 phi_a2; - s8 phi_v1; - - phi_a2 = arg2; - phi_v1 = 0; - if (arg2 < 0x80) { - phi_a2 = 0x80; + if (waveId < 128) { + stubbed_printf("Audio:Wavemem: Bad voiceno (%d)\n", waveId); + waveId = 128; } - temp_f2 = arg1->unk24; - phi_f0 = temp_f2; - if (arg1->unk8 != 0) { - temp_f12 = arg1->unk14; - if (temp_f12 > 0.0f) { - phi_f0 = temp_f2 * (temp_f12 + 1.0f); - } + + freqScale = seqLayer->freqScale; + if (seqLayer->portamento.mode != 0 && 0.0f < seqLayer->portamento.extent) { + freqScale *= (seqLayer->portamento.extent + 1.0f); } - if (phi_f0 < 1.0f) { - phi_f0_2 = D_800F2EC4; + if (freqScale < 1.0f) { + sampleCountIndex = 0; + ratio = 1.0465f; + } else if (freqScale < 2.0f) { + sampleCountIndex = 1; + ratio = 0.52325f; + } else if (freqScale < 4.0f) { + sampleCountIndex = 2; + ratio = 0.26263f; } else { - phi_v1 = 1; - if (phi_f0 < 2.0f) { - phi_f0_2 = D_800F2EC8; - } else { - phi_v1 = 3; - if (phi_f0 < 4.0f) { - phi_f0_2 = D_800F2ECC; - phi_v1 = 2; - } else { - phi_f0_2 = D_800F2ED0; - } - } + sampleCountIndex = 3; + ratio = 0.13081f; } - arg1->unk24 = temp_f2 * phi_f0_2; - arg0->unk31 = phi_a2; - arg0->unk32 = phi_v1; - arg0->unkBC = *(&gUnknownWave7 + (phi_a2 * 4)) + (phi_v1 << 7); - return phi_v1; -} -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD160.s") -#endif + seqLayer->freqScale *= ratio; + note->waveId = waveId; + note->sampleCountIndex = sampleCountIndex; -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800BD160(u8); // extern -extern ? D_800E98F4; + note->noteSubEu.sound.samples = &gWaveSamples[waveId - 128][sampleCountIndex * 64]; -void func_800BD264(void *arg0, void *arg1) { - s32 sp1C; - u8 temp_a2; - u8 phi_a2; + return sampleCountIndex; +} - temp_a2 = arg1->unk1; - phi_a2 = temp_a2; - if (temp_a2 == 0xFF) { - phi_a2 = arg1->unk4C->unk1C; +void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) { + s32 sampleCountIndex; + s32 waveSampleCountIndex; + s32 waveId = seqLayer->instOrWave; + if (waveId == 0xff) { + waveId = seqLayer->seqChannel->instOrWave; } - sp1C = arg0->unk32; - arg0->unk18 = (arg0->unk18 * *(&D_800E98F4 + func_800BD160(phi_a2))) / *(&D_800E98F4 + sp1C); + sampleCountIndex = note->sampleCountIndex; + waveSampleCountIndex = build_synthetic_wave(note, seqLayer, waveId); + note->synthesisState.samplePosInt = note->synthesisState.samplePosInt * D_800E98F4[waveSampleCountIndex] / D_800E98F4[sampleCountIndex]; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD264.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD308(void *arg0) { - arg0->unk0 = arg0; - arg0->unk4 = arg0; - arg0->unk8 = 0; +void init_note_list(struct AudioListItem *list) { + list->prev = list; + list->next = list; + list->u.count = 0; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD308.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD308(s32); // extern - -void func_800BD318(void *arg0) { - func_800BD308(); - func_800BD308(arg0 + 0x10); - func_800BD308(arg0 + 0x20); - func_800BD308(arg0 + 0x30); - arg0->unkC = arg0; - arg0->unk1C = arg0; - arg0->unk2C = arg0; - arg0->unk3C = arg0; +void init_note_lists(struct NotePool *pool) { + init_note_list(&pool->disabled); + init_note_list(&pool->decaying); + init_note_list(&pool->releasing); + init_note_list(&pool->active); + pool->disabled.pool = pool; + pool->decaying.pool = pool; + pool->releasing.pool = pool; + pool->active.pool = pool; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD318.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD318(? *); // extern -void func_800BF004(? *, s32); // extern -extern s32 D_803B1508; -extern ? D_803B5FC8; -extern s32 gMaxSimultaneousNotes; - -void func_800BD368(void) { - s32 temp_s1; - s32 temp_v0; - s32 phi_s0; - s32 phi_s1; - - func_800BD318(&D_803B5FC8); - phi_s0 = 0; - phi_s1 = 0; - if (gMaxSimultaneousNotes > 0) { - do { - temp_v0 = D_803B1508; - (temp_v0 + phi_s0)->unk8 = phi_s0 + temp_v0; - *(D_803B1508 + phi_s0) = 0; - func_800BF004(&D_803B5FC8, phi_s0 + D_803B1508); - temp_s1 = phi_s1 + 1; - phi_s0 += 0xC0; - phi_s1 = temp_s1; - } while (temp_s1 < gMaxSimultaneousNotes); +void init_note_free_list(void) { + s32 i; + + init_note_lists(&gNoteFreeLists); + for (i = 0; i < gMaxSimultaneousNotes; i++) { + gNotes[i].listItem.u.value = &gNotes[i]; + gNotes[i].listItem.prev = NULL; + audio_list_push_back(&gNoteFreeLists.disabled, &gNotes[i].listItem); } } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD368.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD6F4(s32, ? *, ? *); // extern -void func_800BF004(? *, s32); // extern -extern ? D_803B5FC8; -extern ? D_803B5FD8; -extern ? D_803B5FE8; -extern ? D_803B5FF8; - -void func_800BD418(void *arg0) { - void *sp48; - ? *sp40; - s32 temp_s0; - s32 temp_s3; - s32 phi_s3; - s32 phi_s0; - void *phi_s1; - s32 phi_s0_2; - ? *phi_a1; - ? *phi_a2; - ? *phi_s2; - void *phi_s1_2; - ? *phi_a1_2; - ? *phi_a2_2; - ? *phi_v1; - ? *phi_v0; - - phi_s3 = 0; - phi_a1_2 = &D_803B5FD8; - phi_a2_2 = &D_803B5FC8; - phi_s1_2 = sp48; - phi_s2 = sp40; - phi_v1 = &D_803B5FE8; - phi_v0 = &D_803B5FF8; - do { - phi_a1 = phi_a1_2; - phi_a2 = phi_a2_2; - if (phi_s3 != 0) { - if (phi_s3 != 1) { - if (phi_s3 != 2) { - if (phi_s3 != 3) { +void note_pool_clear(struct NotePool *pool) { + s32 i; + struct AudioListItem *source; + struct AudioListItem *cur; + struct AudioListItem *dest; + UNUSED s32 j; // unused in EU + + for (i = 0; i < 4; i++) { + switch (i) { + case 0: + source = &pool->disabled; + dest = &gNoteFreeLists.disabled; + break; + + case 1: + source = &pool->decaying; + dest = &gNoteFreeLists.decaying; + break; + + case 2: + source = &pool->releasing; + dest = &gNoteFreeLists.releasing; + break; + + case 3: + source = &pool->active; + dest = &gNoteFreeLists.active; + break; + } - } else { - phi_s1_2 = arg0 + 0x30; - phi_s2 = phi_v0; - } - } else { - phi_s1_2 = arg0 + 0x20; - phi_s2 = phi_v1; - } - } else { - phi_s1_2 = arg0 + 0x10; - phi_s2 = phi_a1_2; + for (;;) { + cur = source->next; + if (cur == source) { + break; } - phi_s0 = phi_s1_2->unk4; - phi_s1 = phi_s1_2; - } else { - phi_s0 = arg0->unk4; - phi_s1 = arg0; - phi_s2 = phi_a2_2; - } - phi_s0_2 = phi_s0; - phi_s1_2 = phi_s1; - if (phi_s0 != phi_s1) { -loop_12: - phi_a1_2 = phi_a1; - phi_a2_2 = phi_a2; - if (phi_s0_2 != 0) { - func_800BD6F4(phi_s0_2, phi_a1, phi_a2); - func_800BF004(phi_s2, phi_s0_2); - temp_s0 = phi_s1->unk4; - phi_s0_2 = temp_s0; - phi_a1 = &D_803B5FD8; - phi_a2 = &D_803B5FC8; - phi_a1_2 = &D_803B5FD8; - phi_a2_2 = &D_803B5FC8; - phi_v1 = &D_803B5FE8; - phi_v0 = &D_803B5FF8; - phi_v1 = &D_803B5FE8; - phi_v0 = &D_803B5FF8; - if (temp_s0 != phi_s1) { - goto loop_12; - } + if (cur == NULL) { + eu_stubbed_printf_0("Audio: C-Alloc : Dealloc voice is NULL\n"); + break; } + audio_list_remove(cur); + audio_list_push_back(dest, cur); } - temp_s3 = phi_s3 + 1; - phi_s3 = temp_s3; - } while (temp_s3 != 4); - sp40 = phi_s2; - sp48 = phi_s1; + } } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD418.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD418(); // extern -void func_800BF004(s32, s32); // extern -s32 func_800BF044(? *); // extern -extern ? D_803B5FC8; -extern ? D_803B5FD8; -extern ? D_803B5FE8; -extern ? D_803B5FF8; - -void func_800BD578(s32 arg0, s32 arg1) { - ? *sp48; - s32 sp44; - s32 temp_s0; - s32 temp_v0; - s32 phi_s4; - s32 phi_s0; - ? *phi_s1; - s32 phi_s2; - s32 phi_s0_2; - s32 phi_s0_3; - - func_800BD418(); - phi_s4 = 0; - phi_s0 = 0; - if (arg1 > 0) { - phi_s1 = sp48; - phi_s2 = sp44; -loop_2: - phi_s0_2 = phi_s0; - phi_s0_3 = phi_s0; - if (phi_s4 != 4) { - if (phi_s4 != 0) { - if (phi_s4 != 1) { - if (phi_s4 != 2) { - if (phi_s4 != 3) { +void note_pool_fill(struct NotePool *pool, s32 count) { + s32 i; + s32 j; + struct Note *note; + struct AudioListItem *source; + struct AudioListItem *dest; - } else { - phi_s1 = &D_803B5FF8; - phi_s2 = arg0 + 0x30; - } - } else { - phi_s1 = &D_803B5FE8; - phi_s2 = arg0 + 0x20; - } - } else { - phi_s1 = &D_803B5FD8; - phi_s2 = arg0 + 0x10; - } - } else { - phi_s1 = &D_803B5FC8; - phi_s2 = arg0; - } - if (phi_s0 < arg1) { -loop_13: - temp_v0 = func_800BF044(phi_s1); - phi_s0_3 = phi_s0_2; - if (temp_v0 != 0) { - func_800BF004(phi_s2, temp_v0); - temp_s0 = phi_s0_2 + 1; - phi_s0_2 = temp_s0; - phi_s0_3 = temp_s0; - if (temp_s0 < arg1) { - goto loop_13; - } - } - } - phi_s4 += 1; - phi_s0 = phi_s0_3; - if (phi_s0_3 >= arg1) { - sp44 = phi_s2; - sp48 = phi_s1; - } else { - goto loop_2; + note_pool_clear(pool); + + for (i = 0, j = 0; j < count; i++) { + if (i == 4) { + eu_stubbed_printf_1("Alloc Error:Dim voice-Alloc %d", count); + return; + } + + switch (i) { + case 0: + source = &gNoteFreeLists.disabled; + dest = &pool->disabled; + break; + + case 1: + source = &gNoteFreeLists.decaying; + dest = &pool->decaying; + break; + + case 2: + source = &gNoteFreeLists.releasing; + dest = &pool->releasing; + break; + + case 3: + source = &gNoteFreeLists.active; + dest = &pool->active; + break; + } + + while (j < count) { + note = audio_list_pop_back(source); + if (note == NULL) { + break; } + audio_list_push_back(dest, ¬e->listItem); + j++; } } } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD578.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD6B4(void *arg0, ? *arg1) { - if (arg1->unk0 == 0) { - arg1->unk0 = arg0; - arg1->unk4 = arg0->unk4; - *arg0->unk4 = arg1; - arg0->unk4 = arg1; - arg0->unk8 = arg0->unk8 + 1; - arg1->unkC = arg0->unkC; +void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *item) { + // add 'item' to the front of the list given by 'list', if it's not in any list + if (item->prev != NULL) { + eu_stubbed_printf_0("Error:Same List Add\n"); + } else { + item->prev = list; + item->next = list->next; + list->next->prev = item; + list->next = item; + list->u.count++; + item->pool = list->pool; } } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD6B4.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD6F4(void *arg0) { - void *temp_v0; - temp_v0 = arg0->unk0; - if (temp_v0 != 0) { - temp_v0->unk4 = arg0->unk4; - *arg0->unk4 = arg0->unk0; - arg0->unk0 = NULL; +void audio_list_remove(struct AudioListItem *item) { + // remove 'item' from the list it's in, if any + if (item->prev == NULL) { + eu_stubbed_printf_0("Already Cut\n"); + } else { + item->prev->next = item->next; + item->next->prev = item->prev; + item->prev = NULL; } } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD6F4.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD6F4(void *, void *); // extern - -void *func_800BD720(void *arg0, s32 arg1) { - void *sp18; - void *temp_v0; - void *temp_v0_2; - void *phi_a0; - void *phi_v0; - void *phi_a0_2; - void *phi_a0_3; - - temp_v0 = arg0->unk4; - phi_v0 = temp_v0; - if (temp_v0 == arg0) { +struct Note *pop_node_with_lower_prio(struct AudioListItem *list, s32 limit) { + struct AudioListItem *cur = list->next; + struct AudioListItem *best; + + if (cur == list) { return NULL; } - phi_a0 = temp_v0; - phi_a0_2 = temp_v0; - if (temp_v0 != arg0) { - do { - phi_a0_3 = phi_a0; - if (phi_a0->unk8->unk30 >= phi_v0->unk8->unk30) { - phi_a0_3 = phi_v0; - } - temp_v0_2 = phi_v0->unk4; - phi_a0 = phi_a0_3; - phi_v0 = temp_v0_2; - phi_a0_2 = phi_a0_3; - } while (temp_v0_2 != arg0); + + for (best = cur; cur != list; cur = cur->next) { + if (((struct Note *) best->u.value)->priority >= ((struct Note *) cur->u.value)->priority) { + best = cur; + } } - if (phi_a0_2 == 0) { + + if (best == NULL) { return NULL; } - if (phi_a0_2->unk8->unk30 >= arg1) { + + if (limit <= ((struct Note *) best->u.value)->priority) { return NULL; } - sp18 = phi_a0_2; - func_800BD6F4(phi_a0_2, arg0); - return phi_a0_2->unk8; + + audio_list_remove(best); + return best->u.value; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD720.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BCAB4(); // extern -s32 func_800BD160(void *, void *, s32); // extern - -void func_800BD7C0(void *arg0, void *arg1) { - void *sp1C; - u8 temp_a2; - void *temp_a1; - void *temp_v0; - s32 phi_a2; - void *phi_a1; - - arg0->unk40 = -1; - arg0->unk44 = arg1; - arg0->unk30 = arg1->unk4C->unk5; - arg1->unk2 = 3; - arg1->unk0 = arg1->unk0 | 4; - arg1->unk40 = arg0; - arg1->unk4C->unk38 = arg0; - arg1->unk4C->unk3C = arg1; - arg1->unk2C = 0.0f; - func_800BCAB4(); - temp_a1 = arg1; - temp_a2 = temp_a1->unk1; - temp_v0 = arg0 + 0xB0; - phi_a2 = temp_a2; - phi_a1 = temp_a1; - if (temp_a2 == 0xFF) { - phi_a2 = temp_a1->unk4C->unk1C; - } - temp_v0->unkC = temp_a1->unk48; - if (phi_a2 >= 0x80) { - temp_v0->unk1 = temp_v0->unk1 | 2; +void note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer) { + UNUSED s32 pad[4]; + s16 instId; + struct NoteSubEu *sub = ¬e->noteSubEu; + + note->prevParentLayer = NO_LAYER; + note->parentLayer = seqLayer; + note->priority = seqLayer->seqChannel->notePriority; + seqLayer->notePropertiesNeedInit = TRUE; + seqLayer->status = SOUND_LOAD_STATUS_DISCARDABLE; // "loaded" + seqLayer->note = note; + seqLayer->seqChannel->noteUnused = note; + seqLayer->seqChannel->layerUnused = seqLayer; + seqLayer->noteVelocity = 0.0f; + note_init(note); + instId = seqLayer->instOrWave; + if (instId == 0xff) { + instId = seqLayer->seqChannel->instOrWave; + } + sub->sound.audioBankSound = seqLayer->sound; + + if (instId >= 0x80) { + sub->isSyntheticWave = TRUE; } else { - temp_v0->unk1 = temp_v0->unk1 & 0xFFFD; + sub->isSyntheticWave = FALSE; } - if (temp_v0->unk0 & 0x20000) { - sp1C = temp_v0; - arg1 = temp_a1; - func_800BD160(arg0, temp_a1, phi_a2); - phi_a1 = arg1; + + if (sub->isSyntheticWave) { + build_synthetic_wave(note, seqLayer, instId); } - (arg0 + 0xB0)->unk2 = phi_a1->unk4C->unk6; - (arg0 + 0xB0)->unk0 = ((((phi_a1->unk4C->unk0 << 5) >> 0x1F) * 2) & 2) | ((arg0 + 0xB0)->unk0 & 0xFFFD); - (arg0 + 0xB0)->unk1 = ((phi_a1->unk4C->unk7 & 3) << 5) | ((arg0 + 0xB0)->unk1 & 0xFF1F); + sub->bankId = seqLayer->seqChannel->bankId; + sub->stereoHeadsetEffects = seqLayer->seqChannel->stereoHeadsetEffects; + sub->reverbIndex = seqLayer->seqChannel->reverbIndex & 3; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD7C0.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD140(s32); // extern -void func_800BD8F4(void *arg0, s32 arg1) { - func_800BD140(arg0->unk44); - arg0->unk48 = arg1; +void func_800BD8F4(struct Note *note, struct SequenceChannelLayer *seqLayer) { + seq_channel_layer_note_release(note->parentLayer); + note->wantedParentLayer = seqLayer; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD8F4.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern f32 D_803B70A0; - -void func_800BD928(void *arg0, s32 arg1) { - arg0->unk48 = arg1; - arg0->unk30 = 1; - arg0->unk58 = arg0->unk58 | 0x10; - arg0->unk68 = D_803B70A0; +void note_release_and_take_ownership(struct Note *note, struct SequenceChannelLayer *seqLayer) { + note->wantedParentLayer = seqLayer; + note->priority = NOTE_PRIORITY_STOPPING; + note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; + note->adsr.action |= ADSR_ACTION_RELEASE; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD928.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD6B4(s32, s32); // extern -void func_800BD7C0(s32, s32); // extern -s32 func_800BF044(); // extern - -s32 func_800BD950(s32 arg0, s32 arg1) { - s32 sp1C; - s32 temp_v0; - - temp_v0 = func_800BF044(); - sp1C = temp_v0; - if (temp_v0 != 0) { - func_800BD7C0(temp_v0, arg1); - func_800BD6B4(arg0 + 0x30, sp1C); +struct Note *alloc_note_from_disabled(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { + struct Note *note = audio_list_pop_back(&pool->disabled); + if (note != NULL) { + note_init_for_layer(note, seqLayer); + audio_list_push_front(&pool->active, ¬e->listItem); } - return sp1C; + return note; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD950.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD928(s32, s32); // extern -void func_800BF004(s32, s32); // extern -s32 func_800BF044(s32); // extern - -s32 func_800BD99C(s32 arg0, s32 arg1) { - s32 sp1C; - s32 temp_v0; - - temp_v0 = func_800BF044(arg0 + 0x10); - sp1C = temp_v0; - if (temp_v0 != 0) { - func_800BD928(temp_v0, arg1); - func_800BF004(arg0 + 0x20, sp1C); +struct Note *alloc_note_from_decaying(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { + struct Note *note = audio_list_pop_back(&pool->decaying); + if (note != NULL) { + note_release_and_take_ownership(note, seqLayer); + audio_list_push_back(&pool->releasing, ¬e->listItem); } - return sp1C; + return note; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD99C.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800BD720(s32, u8); // extern -void func_800BD8F4(s32, void *); // extern -void func_800BF004(s32, s32); // extern - -s32 func_800BD9EC(s32 arg0, void *arg1) { - s32 sp1C; - s32 temp_v0; - - temp_v0 = func_800BD720(arg0 + 0x30, arg1->unk4C->unk5); - sp1C = temp_v0; - if (temp_v0 != 0) { - func_800BD8F4(temp_v0, arg1); - func_800BF004(arg0 + 0x20, sp1C); +s32 alloc_note_from_active(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { + struct Note *aNote; + + aNote = pop_node_with_lower_prio(&pool->active, seqLayer->seqChannel->notePriority); + + if (aNote == NULL) { + eu_stubbed_printf_0("Audio: C-Alloc : lowerPrio is NULL\n"); + } else { + func_800BD8F4(aNote, seqLayer); + audio_list_push_back(&pool->releasing, &aNote->listItem); } - return sp1C; + + return aNote; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BD9EC.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD6F4(void *); // extern -void func_800BD928(void *, void *, void *); // extern -void *func_800BD950(? *, void *, void *); // extern -void *func_800BD99C(? *, void *, void *); // extern -void *func_800BD9EC(? *, void *, void *); // extern -void func_800BF004(s32, void *); // extern -extern ? D_803B5FC8; - -void *func_800BDA44(void *arg0, void *arg2) { - void *sp24; - u8 temp_v0; - void *temp_a2; - void *temp_v0_10; - void *temp_v0_11; - void *temp_v0_12; - void *temp_v0_13; - void *temp_v0_14; - void *temp_v0_15; - void *temp_v0_16; - void *temp_v0_17; - void *temp_v0_18; - void *temp_v0_19; - void *temp_v0_20; - void *temp_v0_21; - void *temp_v0_22; - void *temp_v0_2; - void *temp_v0_3; - void *temp_v0_4; - void *temp_v0_5; - void *temp_v0_6; - void *temp_v0_7; - void *temp_v0_8; - void *temp_v0_9; - void *temp_v1; - void *phi_a2; - void *phi_a2_2; - - temp_v1 = arg0->unk4C; - temp_v0 = temp_v1->unk2; - phi_a2 = arg2; - if (((temp_v0 & 1) != 0) && (temp_a2 = arg0->unk40, phi_a2 = temp_a2, (temp_a2 != 0)) && (arg0 == temp_a2->unk40) && (temp_a2->unk48 == -1)) { - sp24 = temp_a2; - func_800BD928(temp_a2, arg0, temp_a2); - func_800BD6F4(sp24); - func_800BF004(sp24->unkC + 0x20, sp24); - return sp24; +struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { + struct Note *ret; + u32 policy = seqLayer->seqChannel->noteAllocPolicy; + + if (policy & NOTE_ALLOC_LAYER) { + ret = seqLayer->note; + if (ret != NULL && ret->prevParentLayer == seqLayer + && ret->wantedParentLayer == NO_LAYER + ) { + note_release_and_take_ownership(ret, seqLayer); + audio_list_remove(&ret->listItem); + audio_list_push_back(&ret->listItem.pool->releasing, &ret->listItem); + return ret; + } } - if ((temp_v0 & 2) != 0) { - temp_v0_2 = func_800BD950(temp_v1 + 0x84, arg0, phi_a2); - phi_a2_2 = temp_v0_2; - if ((temp_v0_2 == 0) && (temp_v0_3 = func_800BD99C(arg0->unk4C + 0x84, arg0, temp_v0_2), phi_a2_2 = temp_v0_3, (temp_v0_3 == 0)) && (temp_v0_4 = func_800BD9EC(arg0->unk4C + 0x84, arg0, temp_v0_3), phi_a2_2 = temp_v0_4, (temp_v0_4 == 0))) { - arg0->unk2 = 0; + + if (policy & NOTE_ALLOC_CHANNEL) { + if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))) { + eu_stubbed_printf_0("Sub Limited Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; return NULL; } - goto block_36; - } - if ((temp_v0 & 4) != 0) { - temp_v0_5 = func_800BD950(temp_v1 + 0x84, arg0, phi_a2); - phi_a2_2 = temp_v0_5; - if ((temp_v0_5 == 0) && (temp_v0_6 = func_800BD950(arg0->unk4C->unk44 + 0x94, arg0, temp_v0_5), phi_a2_2 = temp_v0_6, (temp_v0_6 == 0)) && (temp_v0_7 = func_800BD99C(arg0->unk4C + 0x84, arg0, temp_v0_6), phi_a2_2 = temp_v0_7, (temp_v0_7 == 0)) && (temp_v0_8 = func_800BD99C(arg0->unk4C->unk44 + 0x94, arg0, temp_v0_7), phi_a2_2 = temp_v0_8, (temp_v0_8 == 0)) && (temp_v0_9 = func_800BD9EC(arg0->unk4C + 0x84, arg0, temp_v0_8), phi_a2_2 = temp_v0_9, (temp_v0_9 == 0)) && (temp_v0_10 = func_800BD9EC(arg0->unk4C->unk44 + 0x94, arg0, temp_v0_9), phi_a2_2 = temp_v0_10, (temp_v0_10 == 0))) { - arg0->unk2 = 0; + return ret; + } + + if (policy & NOTE_ALLOC_SEQ) { + if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_disabled(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))) { + eu_stubbed_printf_0("Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; return NULL; } - goto block_36; + return ret; } - if ((temp_v0 & 8) != 0) { - temp_v0_11 = func_800BD950(&D_803B5FC8, arg0, phi_a2); - phi_a2_2 = temp_v0_11; - if ((temp_v0_11 == 0) && (temp_v0_12 = func_800BD99C(&D_803B5FC8, arg0, temp_v0_11), phi_a2_2 = temp_v0_12, (temp_v0_12 == 0)) && (temp_v0_13 = func_800BD9EC(&D_803B5FC8, arg0, temp_v0_12), phi_a2_2 = temp_v0_13, (temp_v0_13 == 0))) { - arg0->unk2 = 0; + + if (policy & NOTE_ALLOC_GLOBAL_FREELIST) { + if (!(ret = alloc_note_from_disabled(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_decaying(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) { + eu_stubbed_printf_0("Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; return NULL; } - goto block_36; - } - temp_v0_14 = func_800BD950(temp_v1 + 0x84, arg0, phi_a2); - phi_a2_2 = temp_v0_14; - if ((temp_v0_14 == 0) && (temp_v0_15 = func_800BD950(arg0->unk4C->unk44 + 0x94, arg0, temp_v0_14), phi_a2_2 = temp_v0_15, (temp_v0_15 == 0)) && (temp_v0_16 = func_800BD950(&D_803B5FC8, arg0, temp_v0_15), phi_a2_2 = temp_v0_16, (temp_v0_16 == 0)) && (temp_v0_17 = func_800BD99C(arg0->unk4C + 0x84, arg0, temp_v0_16), phi_a2_2 = temp_v0_17, (temp_v0_17 == 0)) && (temp_v0_18 = func_800BD99C(arg0->unk4C->unk44 + 0x94, arg0, temp_v0_17), phi_a2_2 = temp_v0_18, (temp_v0_18 == 0)) && (temp_v0_19 = func_800BD99C(&D_803B5FC8, arg0, temp_v0_18), phi_a2_2 = temp_v0_19, (temp_v0_19 == 0)) && (temp_v0_20 = func_800BD9EC(arg0->unk4C + 0x84, arg0, temp_v0_19), phi_a2_2 = temp_v0_20, (temp_v0_20 == 0)) && (temp_v0_21 = func_800BD9EC(arg0->unk4C->unk44 + 0x94, arg0, temp_v0_20), phi_a2_2 = temp_v0_21, (temp_v0_21 == 0)) && (temp_v0_22 = func_800BD9EC(&D_803B5FC8, arg0, temp_v0_21), phi_a2_2 = temp_v0_22, (temp_v0_22 == 0))) { - arg0->unk2 = 0; + return ret; + } + + if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_disabled(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_disabled(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) { + eu_stubbed_printf_0("Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; return NULL; } -block_36: - return phi_a2_2; + return ret; } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BDA44.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 soundAlloc(? *, ?); // extern -extern ? gNotesAndBuffersPool; -extern s32 D_803B1508; -extern s32 gMaxSimultaneousNotes; -extern NoteSub gZeroNoteSub; - -void func_800BDD34(void) { - s32 temp_s1; - void *temp_s0; - s32 phi_s2; - s32 phi_s1; - - phi_s1 = 0; - if (gMaxSimultaneousNotes > 0) { - phi_s2 = 0; - do { - temp_s0 = phi_s2 + D_803B1508; - temp_s0->unkB0 = gZeroNoteSub.unk0; - temp_s0->unkB4 = gZeroNoteSub.unk4; - temp_s0->unkB8 = gZeroNoteSub.unk8; - temp_s0->unk30 = 0; - temp_s0->unk44 = -1; - temp_s0->unk48 = -1; - temp_s0->unk40 = -1; - temp_s0->unk31 = 0; - temp_s0->unk54 = 0.0f; - temp_s0->unk34 = 0; - temp_s0->unk59 = 0; - temp_s0->unk58 = 0; - temp_s0->unkA0 = 0; - temp_s0->unk80 = 0.0f; - temp_s0->unk84 = 0.0f; - temp_s0->unkBC = gZeroNoteSub.unkC; - temp_s0->unk1C = soundAlloc(&gNotesAndBuffersPool, 0xA0); - temp_s1 = phi_s1 + 1; - phi_s2 += 0xC0; - phi_s1 = temp_s1; - } while (temp_s1 < gMaxSimultaneousNotes); +void note_init_all(void) { + struct Note *note; + s32 i; + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + note = &gNotes[i]; + note->noteSubEu = gZeroNoteSub; + note->priority = NOTE_PRIORITY_DISABLED; + note->parentLayer = NO_LAYER; + note->wantedParentLayer = NO_LAYER; + note->prevParentLayer = NO_LAYER; + note->waveId = 0; + note->attributes.velocity = 0.0f; + note->adsrVolScale = 0; + note->adsr.state = ADSR_STATE_DISABLED; + note->adsr.action = 0; + note->vibratoState.active = FALSE; + note->portamento.cur = 0.0f; + note->portamento.speed = 0.0f; + // This only works if NoteSynthesisBuffers are size 0xA0. See internal.h + note->synthesisState.synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers)); } } -#else -GLOBAL_ASM("asm/non_matchings/audio/playback/func_800BDD34.s") -#endif diff --git a/src/audio/playback.h b/src/audio/playback.h new file mode 100644 index 000000000..e2cd88bb8 --- /dev/null +++ b/src/audio/playback.h @@ -0,0 +1,49 @@ +#ifndef AUDIO_PLAYBACK_H +#define AUDIO_PLAYBACK_H + +#include <PR/ultratypes.h> + +#include "internal.h" + +// Mask bits denoting where to allocate notes from, according to a channel's +// noteAllocPolicy. Despite being checked as bitmask bits, the bits are not +// orthogonal; rather, the smallest bit wins, except for NOTE_ALLOC_LAYER, +// which *is* orthogonal to the other. SEQ implicitly includes CHANNEL. +// If none of the CHANNEL/SEQ/GLOBAL_FREELIST bits are set, all three locations +// are tried. +#define NOTE_ALLOC_LAYER 1 +#define NOTE_ALLOC_CHANNEL 2 +#define NOTE_ALLOC_SEQ 4 +#define NOTE_ALLOC_GLOBAL_FREELIST 8 + +void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbVol); +void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput); +s32 build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer, s32 waveId); +void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer); +void init_note_list(struct AudioListItem *list); +void init_note_lists(struct NotePool *pool); +void init_note_free_list(void); +void note_pool_clear(struct NotePool *pool); +void note_pool_fill(struct NotePool *pool, s32 count); +void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *item); +void audio_list_remove(struct AudioListItem *item); +struct Note *pop_node_with_lower_prio(struct AudioListItem *list, s32 limit); +void note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer); +void note_disable(struct Note *note); +void process_notes(void); +struct AudioBankSound *instrument_get_audio_bank_sound(struct Instrument *instrument, s32 semitone); +struct Instrument *get_instrument_inner(s32 bankId, s32 instId); +struct Drum *get_drum(s32 bankId, s32 drumId); +void note_init(struct Note *note); +void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLayer, s32 target); +void seq_channel_layer_note_decay(struct SequenceChannelLayer *seqLayer); +void seq_channel_layer_note_release(struct SequenceChannelLayer *seqLayer); +void func_800BD8F4(struct Note *note, struct SequenceChannelLayer *seqLayer); +void note_release_and_take_ownership(struct Note *note, struct SequenceChannelLayer *seqLayer); +struct Note *alloc_note_from_disabled(struct NotePool *pool, struct SequenceChannelLayer *seqLayer); +struct Note *alloc_note_from_decaying(struct NotePool *pool, struct SequenceChannelLayer *seqLayer); +s32 alloc_note_from_active(struct NotePool *pool, struct SequenceChannelLayer *seqLayer); +struct Note *alloc_note(struct SequenceChannelLayer *seqLayer); +void note_init_all(void); + +#endif // AUDIO_PLAYBACK_H diff --git a/src/audio/port_eu.c b/src/audio/port_eu.c index 8d156e570..35bdf86fa 100644 --- a/src/audio/port_eu.c +++ b/src/audio/port_eu.c @@ -1,11 +1,14 @@ #include <ultra64.h> #include <macros.h> +#include "audio/internal.h" +#include "audio/load.h" + #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 s32 func_800B70EC(s32, s32 *, s32, s16); // extern s32 func_800BA00C(); // extern -void func_800BAC04(); // extern +void decrease_sample_dma_ttls(); // extern void func_800CBCB0(void *); // extern extern OSMesgQueue *D_800EA3A8; extern OSMesgQueue *D_800EA3AC; @@ -113,7 +116,7 @@ void *create_next_audio_frame_task(void) { } while (temp_s0_3 != temp_s1_2); } gCurrAudioFrameDmaCount = 0; - func_800BAC04(); + decrease_sample_dma_ttls(); if (osRecvMesg(D_800EA3B0, &sp58, 0) != -1) { D_803B0501 = sp58; D_803B0500 = 5; @@ -180,14 +183,14 @@ GLOBAL_ASM("asm/non_matchings/audio/port_eu/create_next_audio_frame_task.s") void func_800BB388(u8, u8, u8, void *); // extern void func_800BBDDC(u8, ?, void *); // extern void func_800BBEF0(u8, u8, u8, void *); // extern -void func_800BEF2C(u32 *, s32, void *); // extern -void func_800CBA08(u8, s32, void *); // extern +void sequence_player_disable(u32 *, s32, void *); // extern +void seq_player_fade_to_zero_volume(u8, s32, void *); // extern void func_800CBA64(u8, s32); // extern -extern u8 D_803B1510; +extern u8 gSequencePlayers; extern u8 D_803B1658; extern u8 D_803B17A0; extern u8 D_803B18E8; -extern s8 D_803B70B6; +extern s8 gAudioLibSoundMode; void func_800CB818(void *arg0) { s32 temp_a1; @@ -215,32 +218,32 @@ void func_800CB818(void *arg0) { // Duplicate return node #19. Try simplifying control flow for better match return; } - D_803B1510 = (D_803B1510 & 0xFFDF) | 4; + gSequencePlayers = (gSequencePlayers & 0xFFDF) | 4; D_803B1658 = (D_803B1658 & 0xFFDF) | 4; D_803B17A0 = (D_803B17A0 & 0xFFDF) | 4; D_803B18E8 = (D_803B18E8 & 0xFFDF) | 4; return; } - D_803B1510 = D_803B1510 | 0x24; + gSequencePlayers = gSequencePlayers | 0x24; D_803B1658 = D_803B1658 | 0x24; D_803B17A0 = D_803B17A0 | 0x24; D_803B18E8 = D_803B18E8 | 0x24; return; } - D_803B70B6 = temp_a3->unk4; + gAudioLibSoundMode = temp_a3->unk4; return; } goto block_10; } temp_v0_2 = temp_a3->unk1; - temp_a0 = (temp_v0_2 * 0x148) + &D_803B1510; + temp_a0 = (temp_v0_2 * 0x148) + &gSequencePlayers; if ((*temp_a0 >> 0x1F) != 0) { temp_a1 = temp_a3->unk4; if (temp_a1 == 0) { - func_800BEF2C(temp_a0, temp_a1, temp_a3); + sequence_player_disable(temp_a0, temp_a1, temp_a3); return; } - func_800CBA08(temp_v0_2, temp_a1, temp_a3); + seq_player_fade_to_zero_volume(temp_v0_2, temp_a1, temp_a3); return; } return; @@ -260,48 +263,30 @@ block_10: GLOBAL_ASM("asm/non_matchings/audio/port_eu/func_800CB818.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern u32 D_803B1510; - -void func_800CBA08(s32 arg0, s16 arg1) { - ? sp-10; - void *temp_v0; - s16 phi_a1; +void seq_player_fade_to_zero_volume(s32 arg0, s32 fadeOutTime) { + struct SequencePlayer *player; - phi_a1 = arg1; - if (arg1 == 0) { - phi_a1 = 1; + if (fadeOutTime == 0) { + fadeOutTime = 1; } - temp_v0 = (arg0 * 0x148) + &D_803B1510; - temp_v0->unk1 = 2; - temp_v0->unk10 = phi_a1; - temp_v0->unk1C = -(temp_v0->unk18 / phi_a1); + player = &gSequencePlayers[arg0]; + player->state = 2; + player->fadeRemainingFrames = fadeOutTime; + player->fadeVelocity = -(player->fadeVolume / fadeOutTime); } -#else -GLOBAL_ASM("asm/non_matchings/audio/port_eu/func_800CBA08.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern u32 D_803B1510; - -void func_800CBA64(s32 arg0, s16 arg1) { - ? sp-10; - void *temp_v0; +void func_800CBA64(s32 playerIndex, s32 fadeInTime) { + struct SequencePlayer *player; - if (arg1 != 0) { - temp_v0 = (arg0 * 0x148) + &D_803B1510; - temp_v0->unk1 = 1; - temp_v0->unk12 = arg1; - temp_v0->unk10 = arg1; - temp_v0->unk18 = 0.0f; - temp_v0->unk1C = 0.0f; + if (fadeInTime != 0) { + player = &gSequencePlayers[playerIndex]; + player->state = 1; + player->fadeTimerUnkEu = fadeInTime; + player->fadeRemainingFrames = fadeInTime; + player->fadeVolume = 0.0f; + player->fadeVelocity = 0.0f; } } -#else -GLOBAL_ASM("asm/non_matchings/audio/port_eu/func_800CBA64.s") -#endif #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 @@ -410,8 +395,8 @@ GLOBAL_ASM("asm/non_matchings/audio/port_eu/func_800CBC24.s") //generated by mips_to_c commit bd0364fa19633bd6201f8007e2d0a7ed87825909 void func_800CB818(void *); /* extern */ extern ? D_80193820; -extern u32 D_803B1510; -extern ? D_803B5EF0; +extern u32 gSequencePlayers; +extern ? gSequenceChannelNone; void func_800CBCB0(u32 arg0) { s32 temp_s1; @@ -442,7 +427,7 @@ void func_800CBCB0(u32 arg0) { } else { temp_v0 = temp_s0->unk1; if (temp_v0 < 4) { - temp_v1 = &D_803B1510 + (temp_v0 * 0x148); + temp_v1 = &gSequencePlayers + (temp_v0 * 0x148); if ((temp_a0 & 0x80) != 0) { func_800CB818(temp_s0); } else if ((temp_a0 & 0x40) != 0) { @@ -468,7 +453,7 @@ void func_800CBCB0(u32 arg0) { temp_a1 = temp_s0->unk2; if (temp_a1 < 0x10) { temp_v0_2 = (temp_v1 + (temp_a1 * 4))->unk30; - if (temp_v0_2 != &D_803B5EF0) { + if (temp_v0_2 != &gSequenceChannelNone) { switch (temp_a0) { case 1: temp_v0_2->unk1 = temp_v0_2->unk1 | 0x40; @@ -514,13 +499,12 @@ GLOBAL_ASM("asm/non_matchings/audio/port_eu/func_800CBCB0.s") #endif #ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -/* -Failed to decompile function func_800CBF48: +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +? func_800CBAB4(); /* extern */ -Last instruction is missing a delay slot: -jr $ra -*/ +void func_800CBF48(void) { + func_800CBAB4(); +} #else GLOBAL_ASM("asm/non_matchings/audio/port_eu/func_800CBF48.s") #endif diff --git a/src/audio/port_eu.h b/src/audio/port_eu.h new file mode 100644 index 000000000..b651b85b8 --- /dev/null +++ b/src/audio/port_eu.h @@ -0,0 +1,7 @@ +#ifndef AUDIO_PORT_EU_H +#define AUDIO_PORT_EU_H + +void seq_player_fade_to_zero_volume(s32 arg0, s32 fadeOutTime); +void func_800CBA64(s32 playerIndex, s32 fadeInTime); + +#endif
\ No newline at end of file diff --git a/src/audio/seqplayer.c b/src/audio/seqplayer.c index 7424e86f6..111a84a15 100644 --- a/src/audio/seqplayer.c +++ b/src/audio/seqplayer.c @@ -1,561 +1,307 @@ #include <ultra64.h> #include <macros.h> -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD318(void *, void *, s32); // extern - -void func_800BE8F0(void *arg0) { - s32 temp_a0; - u8 temp_t0; - u8 temp_t2; - u8 temp_t4; - u8 temp_t6; - u8 temp_t8; - u8 temp_t8_2; - void *temp_v1; - void *phi_v1; - s32 phi_a0; - - temp_t8 = arg0->unk0 & 0xFF7F; - temp_t0 = temp_t8 & 0xBF; - arg0->unk0 = temp_t8; - temp_t2 = temp_t0 & 0xDF; - arg0->unk0 = temp_t0; - temp_t4 = temp_t2 & 0xEF; - arg0->unk0 = temp_t2; - temp_t6 = temp_t4 & 0xF7; - arg0->unk0 = temp_t4; - temp_t8_2 = temp_t6 & 0xFB; - arg0->unk0 = temp_t6; - arg0->unk0 = temp_t8_2; - arg0->unk10 = 0x800; - arg0->unkC = 0x800; - arg0->unk1E = 0; - arg0->unk0 = temp_t8_2 & 0xFD; - arg0->unk8 = 0; - arg0->unk1 = 0xFF; - arg0->unk78 = 0; - arg0->unk9 = 0x40; - arg0->unkA = 0x80; - arg0->unk38 = 0; - arg0->unk7 = 0; - arg0->unk4 = 0; - arg0->unk5 = 3; - arg0->unk1A = 0; - arg0->unk80 = gDefaultEnvelope; - arg0->unk7C = 0x20; - arg0->unk7D = 0; - arg0->unk12 = 0; - arg0->unkE = 0; - arg0->unk14 = 0; - arg0->unk16 = 0; - arg0->unk18 = 0; - arg0->unk24 = 1.0f; - arg0->unk20 = 1.0f; - arg0->unk30 = 1.0f; - phi_v1 = arg0; - phi_a0 = 0; - do { - temp_a0 = phi_a0 + 4; - phi_v1->unk59 = -1; - phi_v1->unk5A = -1; - phi_v1->unk5B = -1; - temp_v1 = phi_v1 + 4; - temp_v1->unk54 = -1; - phi_v1 = temp_v1; - phi_a0 = temp_a0; - } while (temp_a0 != 8); - arg0->unk0 = arg0->unk0 & 0xFFFE; - func_800BD318(arg0 + 0x84, arg0, 8); +#include "audio/data.h" +#include "audio/internal.h" +#include "audio/seqplayer.h" +#include "audio/load.h" +#include "audio/heap.h" +#include "audio/playback.h" +#include "audio/external.h" + +// sequence_channel_init +void sequence_channel_init(struct SequenceChannel *seqChannel) { + s32 i; + + seqChannel->enabled = FALSE; + seqChannel->finished = FALSE; + seqChannel->stopScript = FALSE; + seqChannel->stopSomething2 = FALSE; + seqChannel->hasInstrument = FALSE; + seqChannel->stereoHeadsetEffects = FALSE; + seqChannel->transposition = 0; + seqChannel->largeNotes = FALSE; + seqChannel->bookOffset = 0; + seqChannel->changes.as_u8 = 0xff; + seqChannel->scriptState.depth = 0; + seqChannel->newPan = 0x40; + seqChannel->panChannelWeight = 0x80; + seqChannel->noteUnused = NULL; + seqChannel->reverbIndex = 0; + seqChannel->reverbVol = 0; + seqChannel->notePriority = NOTE_PRIORITY_DEFAULT; + seqChannel->delay = 0; + seqChannel->adsr.envelope = gDefaultEnvelope; + seqChannel->adsr.releaseRate = 0x20; + seqChannel->adsr.sustain = 0; + seqChannel->vibratoRateTarget = 0x800; + seqChannel->vibratoRateStart = 0x800; + seqChannel->vibratoExtentTarget = 0; + seqChannel->vibratoExtentStart = 0; + seqChannel->vibratoRateChangeDelay = 0; + seqChannel->vibratoExtentChangeDelay = 0; + seqChannel->vibratoDelay = 0; + seqChannel->volume = 1.0f; + seqChannel->volumeScale = 1.0f; + seqChannel->freqScale = 1.0f; + for (i = 0; i < 8; i++) { + seqChannel->soundScriptIO[i] = -1; + } + seqChannel->unused = FALSE; + init_note_lists(&seqChannel->notePool); } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BE8F0.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD120(s32, void *, s32); // extern -s32 func_800BF044(? *, void *, s32); // extern -extern ? D_803B5FB8; - -? func_800BEA10(void *arg0, s32 arg1) { - void *sp1C; - s32 temp_a3; - s32 temp_t7; - s32 temp_v0; - u8 temp_t0; - u8 temp_t1; - u8 temp_t5; - u8 temp_t7_2; - void *temp_a2; - void *temp_v1; +s32 seq_channel_set_layer(struct SequenceChannel *seqChannel, s32 layerIndex) { + struct SequenceChannelLayer *layer; - temp_t7 = arg1 * 4; - temp_a2 = arg0 + temp_t7; - temp_a3 = temp_a2->unk48; - if (temp_a3 == 0) { - sp1C = temp_a2; - temp_v0 = func_800BF044(&D_803B5FB8, temp_a2, temp_a3); - temp_a2->unk48 = temp_v0; - if (temp_v0 == 0) { - temp_a2->unk48 = 0; + if (seqChannel->layers[layerIndex] == NULL) { + struct SequenceChannelLayer *layer; + layer = audio_list_pop_back(&gLayerFreeList); + seqChannel->layers[layerIndex] = layer; + if (layer == NULL) { + seqChannel->layers[layerIndex] = NULL; return -1; } - goto block_4; + } else { + seq_channel_layer_note_decay(seqChannel->layers[layerIndex]); } - sp1C = temp_a2; - func_800BD120(temp_a3, temp_a2, temp_a3); -block_4: - temp_v1 = (arg0 + temp_t7)->unk48; - temp_v1->unk4C = arg0; - temp_t5 = temp_v1->unk0 | 0x80; - temp_t7_2 = temp_t5 & 0xDF; - temp_t0 = temp_t7_2 & 0xEF; - temp_v1->unk18 = arg0->unk7C; - temp_v1->unk0 = temp_t5; - temp_v1->unk1C = arg0->unk80; - temp_t1 = temp_t0 & 0xBF; - temp_v1->unk0 = temp_t7_2; - temp_v1->unk0 = temp_t0; - temp_v1->unk0 = temp_t1; - temp_v1->unk18 = 0; - temp_v1->unk0 = temp_t1 & 0xFD; - temp_v1->unk8 = 0; - temp_v1->unk68 = 0; - temp_v1->unk2 = 0; - temp_v1->unk3 = 0x80; - temp_v1->unk5 = 0x40; - temp_v1->unk22 = 0; - temp_v1->unk38 = 0; - temp_v1->unk3A = 0; - temp_v1->unk3C = 0; - temp_v1->unk40 = 0; - temp_v1->unk44 = 0; - temp_v1->unk1 = 0xFF; - temp_v1->unk28 = 0.0f; - temp_v1->unk24 = 1.0f; + + layer = seqChannel->layers[layerIndex]; + layer->seqChannel = seqChannel; + layer->adsr = seqChannel->adsr; + layer->adsr.releaseRate = 0; + layer->enabled = TRUE; + layer->stopSomething = FALSE; + layer->continuousNotes = FALSE; + layer->finished = FALSE; + layer->ignoreDrumPan = FALSE; + layer->portamento.mode = 0; + layer->scriptState.depth = 0; + layer->status = SOUND_LOAD_STATUS_NOT_LOADED; + layer->noteDuration = 0x80; + layer->pan = 0x40; + layer->transposition = 0; + layer->delay = 0; + layer->duration = 0; + layer->delayUnused = 0; + layer->note = NULL; + layer->instrument = NULL; + layer->freqScale = 1.0f; + layer->velocitySquare = 0.0f; + layer->instOrWave = 0xff; return 0; } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BEA10.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD120(); // extern - -void func_800BEB18(u8 *arg0) { - u8 temp_t0; - u8 temp_t9; - - if (arg0 != 0) { - func_800BD120(); - temp_t9 = *arg0 & 0xFF7F; - temp_t0 = temp_t9 | 0x40; - *arg0 = temp_t9; - *arg0 = temp_t0; +void seq_channel_layer_disable(struct SequenceChannelLayer *layer) { + if (layer != NULL) { + seq_channel_layer_note_decay(layer); + layer->enabled = FALSE; + layer->finished = TRUE; } } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BEB18.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BEB18(s32); // extern -void func_800BF004(? *, s32, s32); // extern -extern ? D_803B5FB8; +void seq_channel_layer_free(struct SequenceChannel *seqChannel, s32 layerIndex) { + struct SequenceChannelLayer *layer = seqChannel->layers[layerIndex]; -void func_800BEB54(s32 arg0, s32 arg1) { - s32 sp1C; - void *sp18; - s32 temp_a2; - void *temp_v0; - - temp_v0 = arg0 + (arg1 * 4); - temp_a2 = temp_v0->unk48; - if (temp_a2 != 0) { - sp18 = temp_v0; - sp1C = temp_a2; - func_800BF004(&D_803B5FB8, temp_a2 + 0x6C, temp_a2); - func_800BEB18(sp1C); - temp_v0->unk48 = 0; + if (layer != NULL) { + audio_list_push_back(&gLayerFreeList, &layer->listItem); + seq_channel_layer_disable(layer); + seqChannel->layers[layerIndex] = NULL; } } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BEB54.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD418(s32); // extern -void func_800BEB54(u8 *, s32); // extern -void func_800BEBA4(u8 *arg0) { - s32 temp_s0; - u8 temp_t9; - s32 phi_s0; +void sequence_channel_disable(struct SequenceChannel *seqChannel) { + s32 i; + for (i = 0; i < LAYERS_MAX; i++) { + seq_channel_layer_free(seqChannel, i); + } - phi_s0 = 0; - do { - func_800BEB54(arg0, phi_s0); - temp_s0 = phi_s0 + 1; - phi_s0 = temp_s0; - } while (temp_s0 != 4); - func_800BD418(arg0 + 0x84); - temp_t9 = *arg0 & 0xFF7F; - *arg0 = temp_t9; - *arg0 = temp_t9 | 0x40; + note_pool_clear(&seqChannel->notePool); + seqChannel->enabled = FALSE; + seqChannel->finished = TRUE; } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BEBA4.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern ? D_803B1A30; -extern u8 D_803B3EF0; -extern ? D_803B5EF0; -? *func_800BEC10(void) { - ? *temp_v1; - ? *phi_v1; - - phi_v1 = &D_803B1A30; -loop_1: - if (phi_v1->unk44 == 0) { - return phi_v1; - } - if (phi_v1->unk108 == 0) { - return phi_v1 + 0xC4; - } - if (phi_v1->unk1CC == 0) { - return phi_v1 + 0x188; - } - if (phi_v1->unk290 == 0) { - return phi_v1 + 0x24C; - } - temp_v1 = phi_v1 + 0x310; - phi_v1 = temp_v1; - if (temp_v1 == &D_803B3EF0) { - return &D_803B5EF0; +struct SequenceChannel *allocate_sequence_channel(void) { + s32 i; + for (i = 0; i < SEQUENCE_CHANNELS; i++) { + if (gSequenceChannels[i].seqPlayer == NULL) { + return &gSequenceChannels[i]; + } } - goto loop_1; + return &gSequenceChannelNone; } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BEC10.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BE8F0(s32); // extern -void func_800BEBA4(s32, s32); // extern -s32 func_800BEC10(); // extern -extern ? D_803B5EF0; -extern s32 D_803B7198; +void sequence_player_init_channels(struct SequencePlayer *seqPlayer, u16 channelBits) { + struct SequenceChannel *seqChannel; + s32 i; -void func_800BEC8C(void *arg0, s32 arg1) { - s32 temp_s0; - s32 temp_s3; - s32 temp_v0; - void *temp_s2; - s32 phi_a1; - s32 phi_s3; - - phi_a1 = arg1 & 0xFFFF; - phi_s3 = 0; - do { - if ((phi_a1 & 1) != 0) { - temp_s2 = arg0 + (phi_s3 * 4); - temp_s0 = temp_s2->unk30; - if (((temp_s0 != &D_803B5EF0) == 1) && (arg0 == temp_s0->unk44)) { - func_800BEBA4(temp_s0, phi_a1); - temp_s0->unk44 = 0; + for (i = 0; i < CHANNELS_MAX; i++) { + if (channelBits & 1) { + seqChannel = seqPlayer->channels[i]; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == TRUE && seqChannel->seqPlayer == seqPlayer) { + sequence_channel_disable(seqChannel); + seqChannel->seqPlayer = NULL; } - temp_v0 = func_800BEC10(); - if (temp_v0 == &D_803B5EF0) { - D_803B7198 = phi_s3 + 0x10000; - temp_s2->unk30 = temp_v0; + seqChannel = allocate_sequence_channel(); + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { + eu_stubbed_printf_0("Audio:Track:Warning: No Free Notetrack\n"); + gAudioErrorFlags = i + 0x10000; + seqPlayer->channels[i] = seqChannel; } else { - func_800BE8F0(temp_v0); - temp_s2->unk30 = temp_v0; - temp_v0->unk44 = arg0; - temp_v0->unk6 = arg0->unk5; - temp_v0->unk3 = arg0->unk3; - temp_v0->unk2 = arg0->unk2; + sequence_channel_init(seqChannel); + seqPlayer->channels[i] = seqChannel; + seqChannel->seqPlayer = seqPlayer; + seqChannel->bankId = seqPlayer->defaultBank[0]; + seqChannel->muteBehavior = seqPlayer->muteBehavior; + seqChannel->noteAllocPolicy = seqPlayer->noteAllocPolicy; } } - temp_s3 = phi_s3 + 1; - phi_a1 = (phi_a1 >> 1) & 0xFFFF; - phi_s3 = temp_s3; - } while (temp_s3 != 0x10); + channelBits = channelBits >> 1; + } } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BEC8C.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BEBA4(s32, s32); // extern -extern ? D_803B5EF0; - -void func_800BEDB8(s32 arg0, s32 arg1) { - s32 temp_s0; - s32 temp_s1; - void *temp_s3; - s32 phi_a1; - s32 phi_s1; - - phi_a1 = arg1 & 0xFFFF; - phi_s1 = 0; - do { - if ((phi_a1 & 1) != 0) { - temp_s3 = arg0 + (phi_s1 * 4); - temp_s0 = temp_s3->unk30; - if ((temp_s0 != &D_803B5EF0) == 1) { - if (arg0 == temp_s0->unk44) { - func_800BEBA4(temp_s0, phi_a1); - temp_s0->unk44 = 0; +void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 channelBits) { + struct SequenceChannel *seqChannel; + s32 i; + + eu_stubbed_printf_0("SUBTRACK DIM\n"); + for (i = 0; i < CHANNELS_MAX; i++) { + if (channelBits & 1) { + seqChannel = seqPlayer->channels[i]; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == TRUE) { + if (seqChannel->seqPlayer == seqPlayer) { + sequence_channel_disable(seqChannel); + seqChannel->seqPlayer = NULL; } - temp_s3->unk30 = &D_803B5EF0; + else { + stubbed_printf("Audio:Track: Warning SUBTRACK PARENT CHANGED\n"); + } + seqPlayer->channels[i] = &gSequenceChannelNone; } } - temp_s1 = phi_s1 + 1; - phi_a1 = (phi_a1 >> 1) & 0xFFFF; - phi_s1 = temp_s1; - } while (temp_s1 != 0x10); + channelBits = channelBits >> 1; + } } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BEDB8.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BEB54(void *, s32); // extern -extern ? D_803B5EF0; - -void func_800BEE88(s32 arg0, s32 arg1, s32 arg2) { - s32 temp_s0; - u8 temp_t4; - void *temp_s2; - void *phi_s1; - s32 phi_s0; - - temp_s2 = (arg0 + ((arg1 & 0xFF) * 4))->unk30; - phi_s0 = 0; - if (temp_s2 != &D_803B5EF0) { - temp_s2->unk78 = 0; - temp_s2->unk60 = arg2; - temp_t4 = temp_s2->unk0 | 0x80; - temp_s2->unk0 = temp_t4; - temp_s2->unk0 = temp_t4 & 0xBF; - temp_s2->unk1A = 0; - phi_s1 = temp_s2; - do { - if (phi_s1->unk48 != 0) { - func_800BEB54(temp_s2, phi_s0); +void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *script) { + struct SequenceChannel *seqChannel = seqPlayer->channels[channelIndex]; + s32 i; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { + stubbed_printf("SEQID %d,BANKID %d\n", seqPlayer->seqId, seqPlayer->defaultBank[0]); + stubbed_printf("ERR:SUBTRACK %d NOT ALLOCATED\n", channelIndex); + } else { + seqChannel->enabled = TRUE; + seqChannel->finished = FALSE; + seqChannel->scriptState.depth = 0; + seqChannel->scriptState.pc = script; + seqChannel->delay = 0; + for (i = 0; i < LAYERS_MAX; i++) { + if (seqChannel->layers[i] != NULL) { + seq_channel_layer_free(seqChannel, i); } - temp_s0 = phi_s0 + 1; - phi_s1 += 4; - phi_s0 = temp_s0; - } while (temp_s0 != 4); + } } } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BEE88.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD418(s32); // extern -void func_800BEDB8(?); // extern -extern u32 D_803AFE18; -extern u8 D_803B03C0; -extern ? D_803B0400; +void sequence_player_disable(struct SequencePlayer *seqPlayer) { + sequence_player_disable_channels(seqPlayer, 0xffff); + note_pool_clear(&seqPlayer->notePool); + seqPlayer->finished = TRUE; + seqPlayer->enabled = FALSE; -void func_800BEF2C(void *arg0) { - u8 *temp_v0; - u8 *temp_v1_2; - u8 temp_a0; - u8 temp_t0; - u8 temp_t9; - u8 temp_v1; - - func_800BEDB8(0xFFFF); - func_800BD418(arg0 + 0x94); - temp_t9 = arg0->unk0 | 0x40; - temp_t0 = temp_t9 & 0x7F; - arg0->unk0 = temp_t9; - arg0->unk0 = temp_t0; - temp_v0 = arg0->unk4 + &D_803B0400; - temp_v1 = *temp_v0; - if ((temp_v1 >= 2) && (temp_v1 != 5)) { - *temp_v0 = 3; + if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) && gSeqLoadStatus[seqPlayer->seqId] != 5) { + gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_DISCARDABLE; } - temp_v1_2 = arg0->unk5 + &D_803B03C0; - temp_a0 = *temp_v1_2; - if ((temp_a0 >= 2) && (temp_a0 != 5)) { - *temp_v1_2 = 4; - } - if (arg0->unk5 == D_803AFE18.unk1B2) { - D_803AFE18.unk194 = 1; - return; + + if (IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) && gBankLoadStatus[seqPlayer->defaultBank[0]] != 5) { + gBankLoadStatus[seqPlayer->defaultBank[0]] = 4; } - if (arg0->unk5 == D_803AFE18.unk1BE) { - D_803AFE18.unk194 = 0; + + // (Note that if this is called from alloc_bank_or_seq, the side will get swapped + // later in that function. Thus, we signal that we want to load into the slot + // of the bank that we no longer need.) + if (seqPlayer->defaultBank[0] == gBankLoadedPool.temporary.entries[0].id) { + gBankLoadedPool.temporary.nextSide = 1; + } else if (seqPlayer->defaultBank[0] == gBankLoadedPool.temporary.entries[1].id) { + gBankLoadedPool.temporary.nextSide = 0; } } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BEF2C.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BF004(void *arg0, void *arg1) { - if (arg1->unk0 == 0) { - arg0->unk0->unk4 = arg1; - arg1->unk4 = arg0; - arg1->unk0 = arg0->unk0; - arg0->unk0 = arg1; - arg0->unk8 = arg0->unk8 + 1; - arg1->unkC = arg0->unkC; +void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item) { + if (item->prev != NULL) { + eu_stubbed_printf_0("Error:Same List Add\n"); + } else { + list->prev->next = item; + item->prev = list->prev; + item->next = list; + list->prev = item; + list->u.count++; + item->pool = list->pool; } } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BF004.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800BF044(void *arg0) { - void *temp_v1; - temp_v1 = arg0->unk0; - if (temp_v1 == arg0) { - return 0; +void *audio_list_pop_back(struct AudioListItem *list) { + struct AudioListItem *item = list->prev; + if (item == list) { + return NULL; } - temp_v1->unk0->unk4 = arg0; - arg0->unk0 = temp_v1->unk0; - temp_v1->unk0 = NULL; - arg0->unk8 = arg0->unk8 - 1; - return temp_v1->unk8; + item->prev->next = list; + list->prev = item->prev; + item->prev = NULL; + list->u.count--; + return item->u.value; } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BF044.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BF004(? *, ? *); // extern -extern u8 D_803B3EF0; -extern ? D_803B3F5C; -extern ? D_803B5F5C; -extern ? D_803B5FB8; +void init_layer_freelist(void) { + s32 i; -void func_800BF084(void) { - ? *temp_s1; - ? *phi_s0; - ? *phi_s1; + gLayerFreeList.prev = &gLayerFreeList; + gLayerFreeList.next = &gLayerFreeList; + gLayerFreeList.u.count = 0; + gLayerFreeList.pool = NULL; - D_803B5FB8.unk0 = &D_803B5FB8; - D_803B5FB8.unk4 = &D_803B5FB8; - D_803B5FB8.unk8 = 0; - D_803B5FB8.unkC = 0; - phi_s0 = &D_803B3EF0; - phi_s1 = &D_803B3F5C; - do { - phi_s0->unk74 = phi_s0; - phi_s0->unk6C = 0; - func_800BF004(&D_803B5FB8, phi_s1); - temp_s1 = phi_s1 + 0x80; - phi_s0 += 0x80; - phi_s1 = temp_s1; - } while (temp_s1 != &D_803B5F5C); + for (i = 0; i < ARRAY_COUNT(gSequenceLayers); i++) { + gSequenceLayers[i].listItem.u.value = &gSequenceLayers[i]; + gSequenceLayers[i].listItem.prev = NULL; + audio_list_push_back(&gLayerFreeList, &gSequenceLayers[i].listItem); + } } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BF084.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -u8 func_800BF108(u8 **arg0) { - u8 *temp_a1; - u8 temp_v0; - - temp_a1 = *arg0; - temp_v0 = *temp_a1; - *arg0 = temp_a1 + 1; - return temp_v0; +u8 m64_read_u8(struct M64ScriptState *state) { + return *(state->pc++); } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BF108.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s16 func_800BF11C(u8 **arg0) { - u8 *temp_a1; - u8 *temp_t9; - u8 temp_v1; - temp_a1 = *arg0; - temp_v1 = *temp_a1; - temp_t9 = temp_a1 + 1; - *arg0 = temp_t9; - *arg0 = temp_t9 + 1; - return *temp_t9 | (temp_v1 << 8); +s16 m64_read_s16(struct M64ScriptState *state) { + s16 ret = *(state->pc++) << 8; + ret = *(state->pc++) | ret; + return ret; } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BF11C.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -u8 func_800BF14C(u8 **arg0) { - u8 *temp_t6; - u8 *temp_v0; - u8 temp_v1; - u8 phi_v1; - - temp_v0 = *arg0; - temp_v1 = *temp_v0; - temp_t6 = temp_v0 + 1; - *arg0 = temp_t6; - phi_v1 = temp_v1; - if ((temp_v1 & 0x80) != 0) { - *arg0 = temp_t6 + 1; - phi_v1 = (*temp_t6 | ((temp_v1 << 8) & 0x7F00)) & 0xFFFF; +u16 m64_read_compressed_u16(struct M64ScriptState *state) { + u16 ret = *(state->pc++); + if (ret & 0x80) { + ret = (ret << 8) & 0x7f00; + ret = *(state->pc++) | ret; } - return phi_v1; + return ret; } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BF14C.s") -#endif #ifdef MIPS_TO_C -//generated by mips_to_c commit bd0364fa19633bd6201f8007e2d0a7ed87825909 -void func_800BD120(void *, s32); /* extern */ -void func_800BD264(void *, void *); /* extern */ -void func_800BE4D4(void *); /* extern */ -void func_800BEB18(void *, s32); /* extern */ +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +struct Note *alloc_note(struct SequenceChannelLayer *); /* extern */ +extern s16 D_803B70B4; -void func_800BF190(void *arg0) { - void *sp68; +void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { + struct SequenceChannel *sp68; s32 sp44; f32 temp_f0; f32 temp_f2; - s16 temp_a0_3; - s16 temp_a0_4; - s16 temp_s3; - s16 temp_s3_2; - s16 temp_s3_3; - s16 temp_s3_4; - s16 temp_s3_6; - s16 temp_v0_10; - s16 temp_v0_12; - s16 temp_v0_13; - s16 temp_v0_7; + f32 var_f0; + f32 var_f0_2; + f32 var_f4; + s16 temp_v0_11; + s16 temp_v0_4; + s16 temp_v0_6; s16 temp_v1; s32 temp_a1; s32 temp_s2; @@ -563,22 +309,36 @@ void func_800BF190(void *arg0) { s32 temp_t5; s32 temp_t6; s32 temp_t8; - s32 temp_v0_11; s32 temp_v0_17; s32 temp_v0_19; s32 temp_v0_3; - s32 temp_v0_4; - s32 temp_v0_6; s32 temp_v0_8; s32 temp_v1_12; s32 temp_v1_6; s32 temp_v1_7; s32 temp_v1_8; + s32 var_a2; + s32 var_s2; + s32 var_s2_2; + s32 var_s2_3; + struct AudioBankSound *temp_v1_13; + struct Drum *temp_v0_15; + struct Instrument *var_a0_2; + struct M64ScriptState *temp_s0; + struct Note *temp_a0_4; + struct Note *temp_a0_5; + struct Portamento *temp_v0_18; + struct SequenceChannel *temp_v0_2; + struct SequencePlayer *temp_s4; + u16 temp_v0_10; + u16 temp_v0_12; + u16 temp_v0_13; u16 temp_v0_14; + u16 temp_v0_7; + u16 var_a0; + u16 var_s3; u32 temp_v0; u32 temp_v0_20; - u8 *temp_t2; - u8 *temp_t6_2; u8 *temp_v1_10; u8 *temp_v1_11; u8 *temp_v1_4; @@ -586,937 +346,846 @@ void func_800BF190(void *arg0) { u8 *temp_v1_9; u8 temp_a0; u8 temp_a0_2; - u8 temp_a0_5; - u8 temp_a2; - u8 temp_a2_2; - u8 temp_a2_3; - u8 temp_s3_5; + u8 temp_a0_3; u8 temp_t4; u8 temp_v0_16; u8 temp_v0_9; u8 temp_v1_2; u8 temp_v1_3; - void *temp_a0_6; - void *temp_a0_7; - void *temp_s0; - void *temp_s4; - void *temp_v0_15; - void *temp_v0_18; - void *temp_v0_2; + u8 var_a2_2; + u8 var_v0; void *temp_v0_5; - void *temp_v1_13; - u8 phi_s2; - s32 phi_a2; - s32 phi_a2_2; - s16 phi_a0; - u8 phi_v0; - s32 phi_s2_2; - s32 phi_a0_2; - s32 phi_a2_3; - f32 phi_f0; - f32 phi_f0_2; - f32 phi_f4; - s32 phi_s2_3; - s16 phi_s3; - s16 phi_s3_2; sp44 = 1; - temp_v0 = arg0->unk0; + temp_v0 = layer->unk0; if ((temp_v0 >> 0x1F) != 0) { - temp_v1 = arg0->unk38; + temp_v1 = layer->delay; if (temp_v1 >= 2) { - arg0->unk38 = temp_v1 - 1; - if (((temp_v0 * 4) >= 0) && (arg0->unk3A >= arg0->unk38)) { - func_800BD120(); - arg0->unk0 = arg0->unk0 | 0x20; - return; + layer->delay = temp_v1 - 1; + if (!(temp_v0 & 0x20000000) && (layer->duration >= layer->delay)) { + seq_channel_layer_note_decay(layer); + layer->unk0 = (s8) ((u8) layer->unk0 | 0x20); } - /* Duplicate return node #139. Try simplifying control flow for better match */ - return; - } - if ((temp_v0 * 8) >= 0) { - func_800BD120(arg0); - } - temp_t8 = arg0->unk8 & ~0x80; - if ((temp_t8 == 1) || (temp_t8 == 2)) { - arg0->unk8 = 0; - } - temp_v0_2 = arg0->unk4C; - temp_s0 = arg0 + 0x50; - temp_s4 = temp_v0_2->unk44; - arg0->unk0 = arg0->unk0 | 4; - sp68 = temp_v0_2; - phi_s3_2 = sp4A; + } else { + if (!(temp_v0 & 0x10000000)) { + seq_channel_layer_note_decay(layer); + } + temp_t8 = layer->portamento.mode & ~0x80; + if ((temp_t8 == 1) || (temp_t8 == 2)) { + layer->portamento.mode = 0; + } + temp_v0_2 = layer->seqChannel; + temp_s0 = &layer->scriptState; + temp_s4 = temp_v0_2->seqPlayer; + layer->unk0 = (s8) ((u8) layer->unk0 | 4); + var_s3 = sp4A; + sp68 = temp_v0_2; loop_11: - temp_v0_3 = func_800BF108(temp_s0, MIPS2C_ERROR(Read from unset register $a1)); - temp_s2 = temp_v0_3 & 0xFF; - phi_s3 = phi_s3_2; - if (temp_v0_3 >= 0xC1) { - if (temp_v0_3 >= 0xCD) { - switch (temp_v0_3) { /* switch 1 */ - case 0xFF: /* switch 1 */ - temp_v1_2 = temp_s0->unk18; + temp_v0_3 = m64_read_u8(temp_s0); + temp_s2 = temp_v0_3 & 0xFF; + if (temp_v0_3 >= 0xC1) { + switch (temp_v0_3) { /* switch 5; irregular */ + case 0xFF: /* switch 5 */ + temp_v1_2 = temp_s0->depth; if (temp_v1_2 == 0) { - func_800BEB18(arg0, temp_v0_3); + seq_channel_layer_disable(layer); return; } temp_t4 = (temp_v1_2 - 1) & 0xFF; - temp_s0->unk18 = temp_t4; - temp_s0->unk0 = (temp_s0 + (temp_t4 * 4))->unk4; + temp_s0->depth = temp_t4; + temp_s0->pc = temp_s0->stack[temp_t4]; goto loop_11; - case 0xFC: /* switch 1 */ - temp_v0_4 = func_800BF11C(temp_s0, temp_v0_3); + case 0xFC: /* switch 5 */ + temp_v0_4 = m64_read_s16(temp_s0); temp_t5 = temp_v0_4 & 0xFFFF; - (temp_s0 + (temp_s0->unk18 * 4))->unk4 = temp_s0->unk0; - temp_s0->unk18 = temp_s0->unk18 + 1; - temp_s0->unk0 = temp_s4->unk14 + temp_t5; - phi_s3_2 = temp_v0_4 & 0xFFFF; + temp_s0->stack[temp_s0->depth] = temp_s0->pc; + var_s3 = temp_v0_4 & 0xFFFF; + temp_s0->depth += 1; + temp_s0->pc = &temp_s4->seqData[temp_t5]; goto loop_11; - case 0xF8: /* switch 1 */ - (temp_s0 + temp_s0->unk18)->unk14 = func_800BF108(temp_s0, temp_v0_3); - (temp_s0 + (temp_s0->unk18 * 4))->unk4 = temp_s0->unk0; - temp_s0->unk18 = temp_s0->unk18 + 1; + case 0xF8: /* switch 5 */ + temp_s0->remLoopIters[temp_s0->depth] = m64_read_u8(temp_s0); + temp_s0->stack[temp_s0->depth] = temp_s0->pc; + temp_s0->depth += 1; goto loop_11; - case 0xF7: /* switch 1 */ - temp_v0_5 = temp_s0 + temp_s0->unk18; - temp_v0_5->unk13 = temp_v0_5->unk13 - 1; - temp_v1_3 = temp_s0->unk18; + case 0xF7: /* switch 5 */ + temp_v0_5 = temp_s0 + temp_s0->depth; + temp_v0_5->unk13 = (u8) (temp_v0_5->unk13 - 1); + temp_v1_3 = temp_s0->depth; if ((temp_s0 + temp_v1_3)->unk13 != 0) { - temp_s0->unk0 = *(temp_s0 + (temp_v1_3 * 4)); + temp_s0->pc = *(temp_s0 + (temp_v1_3 * 4)); } else { - temp_s0->unk18 = temp_v1_3 - 1; + temp_s0->depth = temp_v1_3 - 1; } goto loop_11; - case 0xFB: /* switch 1 */ - temp_v0_6 = func_800BF11C(temp_s0, temp_v0_3); - temp_s3 = temp_v0_6 & 0xFFFF; - temp_s0->unk0 = temp_s4->unk14 + (temp_v0_6 & 0xFFFF); - phi_s3_2 = temp_s3; + case 0xFB: /* switch 5 */ + temp_v0_6 = m64_read_s16(temp_s0); + var_s3 = temp_v0_6 & 0xFFFF; + temp_s0->pc = &temp_s4->seqData[temp_v0_6 & 0xFFFF]; goto loop_11; - case 0xF4: /* switch 1 */ - temp_s0->unk0 = temp_s0->unk0 + func_800BF108(temp_s0, temp_v0_3); + case 0xF4: /* switch 5 */ + temp_s0->pc = &temp_s0->pc[m64_read_u8(temp_s0)]; goto loop_11; - } - } else { - switch (temp_v0_3) { /* switch 2 */ - case 0xC1: /* switch 2 */ - case 0xCA: /* switch 2 */ - temp_v1_4 = temp_s0->unk0; + case 0xC1: /* switch 5 */ + case 0xCA: /* switch 5 */ + temp_v1_4 = temp_s0->pc; temp_a0 = *temp_v1_4; - temp_s0->unk0 = temp_v1_4 + 1; + temp_s0->pc = temp_v1_4 + 1; if (temp_v0_3 == 0xC1) { - arg0->unk28 = (temp_a0 * temp_a0) / 16129.0f; + layer->velocitySquare = (f32) (temp_a0 * temp_a0) / 16129.0f; } else { - arg0->unk5 = temp_a0; + layer->pan = temp_a0; } - break; - case 0xC2: /* switch 2 */ - case 0xC9: /* switch 2 */ - temp_v1_5 = temp_s0->unk0; + goto loop_11; + case 0xC2: /* switch 5 */ + case 0xC9: /* switch 5 */ + temp_v1_5 = temp_s0->pc; temp_a0_2 = *temp_v1_5; - temp_s0->unk0 = temp_v1_5 + 1; + temp_s0->pc = temp_v1_5 + 1; if (temp_v0_3 == 0xC9) { - arg0->unk3 = temp_a0_2; + layer->noteDuration = temp_a0_2; } else { - arg0->unk22 = temp_a0_2; + layer->transposition = (s16) temp_a0_2; } - break; - case 0xC4: /* switch 2 */ - case 0xC5: /* switch 2 */ + goto loop_11; + case 0xC4: /* switch 5 */ + case 0xC5: /* switch 5 */ if (temp_v0_3 == 0xC4) { - arg0->unk0 = arg0->unk0 | 0x10; + layer->unk0 = (s8) ((u8) layer->unk0 | 0x10); } else { - arg0->unk0 = arg0->unk0 & 0xFFEF; + layer->unk0 = (s8) ((u8) layer->unk0 & 0xFFEF); } - func_800BD120(arg0, temp_v0_3); - break; - case 0xC3: /* switch 2 */ - temp_v0_7 = func_800BF14C(temp_s0, temp_v0_3); - temp_s3_2 = temp_v0_7 & 0xFFFF; - arg0->unk34 = temp_v0_7; - phi_s3_2 = temp_s3_2; - break; - case 0xC6: /* switch 2 */ - temp_v0_8 = func_800BF108(temp_s0, temp_v0_3); + seq_channel_layer_note_decay(layer); + goto loop_11; + case 0xC3: /* switch 5 */ + temp_v0_7 = m64_read_compressed_u16(temp_s0); + var_s3 = temp_v0_7 & 0xFFFF; + layer->shortNoteDefaultPlayPercentage = (s16) temp_v0_7; + goto loop_11; + case 0xC6: /* switch 5 */ + temp_v0_8 = m64_read_u8(temp_s0); if (temp_v0_8 >= 0x7F) { if (temp_v0_8 == 0x7F) { - arg0->unk1 = 0; + layer->instOrWave = 0; } else { - arg0->unk1 = temp_v0_8; - arg0->unk44 = 0; + layer->instOrWave = (u8) temp_v0_8; + layer->instrument = NULL; } if (temp_v0_8 == 0xFF) { - arg0->unk18 = 0; + layer->adsr.releaseRate = 0; } } else { - temp_v0_9 = func_800BFC68(sp68, temp_v0_8 & 0xFF & 0xFF, arg0 + 0x44, arg0 + 0x18); - arg0->unk1 = temp_v0_9; + temp_v0_9 = get_instrument(sp68, temp_v0_8 & 0xFF & 0xFF, &layer->instrument, &layer->adsr); + layer->instOrWave = temp_v0_9; if (temp_v0_9 == 0) { - arg0->unk1 = 0xFF; + layer->instOrWave = 0xFF; } } - break; - case 0xC7: /* switch 2 */ - arg0->unk8 = func_800BF108(temp_s0, temp_v0_3); - temp_t6 = (func_800BF108(temp_s0, MIPS2C_ERROR(Read from unset register $a1)) + sp68->unk1E + arg0->unk22 + temp_s4->unkC) & 0xFF; - phi_s2 = temp_t6; + goto loop_11; + case 0xC7: /* switch 5 */ + layer->portamento.mode = m64_read_u8(temp_s0); + temp_t6 = (m64_read_u8(temp_s0) + sp68->transposition + layer->transposition + temp_s4->transposition) & 0xFF; + var_s2 = temp_t6; if (temp_t6 >= 0x80) { - phi_s2 = 0; + var_s2 = 0; } - arg0->unk4 = phi_s2; - if ((arg0->unk8 & 0x80) != 0) { - arg0->unk20 = *temp_s0->unk0; - temp_s0->unk0 = temp_s0->unk0 + 1; + layer->portamentoTargetNote = (u8) var_s2; + if (layer->portamento.mode & 0x80) { + layer->portamentoTime = (u16) *temp_s0->pc; + temp_s0->pc += 1; } else { - temp_v0_10 = func_800BF14C(temp_s0, MIPS2C_ERROR(Read from unset register $a1)); - temp_s3_3 = temp_v0_10 & 0xFFFF; - arg0->unk20 = temp_v0_10; - phi_s3_2 = temp_s3_3; + temp_v0_10 = m64_read_compressed_u16(temp_s0); + var_s3 = temp_v0_10 & 0xFFFF; + layer->portamentoTime = temp_v0_10; } - break; - case 0xC8: /* switch 2 */ - arg0->unk8 = 0; - break; - case 0xCB: /* switch 2 */ - temp_v0_11 = func_800BF11C(temp_s0, temp_v0_3); - temp_s3_4 = temp_v0_11 & 0xFFFF; - arg0->unk1C = temp_s4->unk14 + (temp_v0_11 & 0xFFFF); - arg0->unk18 = func_800BF108(temp_s0, MIPS2C_ERROR(Read from unset register $a1)); - phi_s3_2 = temp_s3_4; - break; - case 0xCC: /* switch 2 */ - arg0->unk0 = arg0->unk0 | 2; - break; - default: /* switch 2 */ - default: /* switch 1 */ + goto loop_11; + case 0xC8: /* switch 5 */ + layer->portamento.mode = 0; + goto loop_11; + case 0xCB: /* switch 5 */ + temp_v0_11 = m64_read_s16(temp_s0); + var_s3 = temp_v0_11 & 0xFFFF; + layer->adsr.envelope = (struct AdsrEnvelope *) &temp_s4->seqData[temp_v0_11 & 0xFFFF]; + layer->adsr.releaseRate = m64_read_u8(temp_s0); + goto loop_11; + case 0xCC: /* switch 5 */ + layer->unk0 = (s8) ((u8) layer->unk0 | 2); + goto loop_11; + default: /* switch 5 */ temp_v1_6 = temp_v0_3 & 0xF0; - if (temp_v1_6 != 0xD0) { - if (temp_v1_6 != 0xE0) { - - } else { - arg0->unk3 = *(temp_s4->unk90 + (temp_v0_3 & 0xF)); - } - } else { - temp_s3_5 = *(temp_s4->unk8C + (temp_v0_3 & 0xF)); - arg0->unk28 = (temp_s3_5 * temp_s3_5) / 16129.0f; - phi_s3_2 = temp_s3_5; + switch (temp_v1_6) { /* switch 6; irregular */ + case 0xD0: /* switch 6 */ + var_s3 = (u16) temp_s4->shortNoteVelocityTable[temp_v0_3 & 0xF]; + layer->velocitySquare = (f32) (var_s3 * var_s3) / 16129.0f; + break; + case 0xE0: /* switch 6 */ + layer->noteDuration = temp_s4->shortNoteDurationTable[temp_v0_3 & 0xF]; + break; } - break; + goto loop_11; } - goto loop_11; - } - } else { - temp_v1_7 = temp_v0_3 & 0xC0; - if (temp_v0_3 == 0xC0) { - arg0->unk38 = func_800BF14C(temp_s0, temp_v0_3); - arg0->unk0 = arg0->unk0 | 0x20; - goto block_119; - } - arg0->unk0 = arg0->unk0 & 0xFFDF; - if (((sp68->unk0 << 6) >> 0x1F) == 1) { - temp_v1_8 = temp_v0_3 & 0xC0; - if (temp_v1_8 != 0) { - if (temp_v1_8 != 0x40) { - phi_a0 = phi_s3_2; - if (temp_v1_8 != 0x80) { - phi_a2 = sp34; + } else { + temp_v1_7 = temp_v0_3 & 0xC0; + if (temp_v0_3 == 0xC0) { + layer->delay = m64_read_compressed_u16(temp_s0); + layer->unk0 = (s8) ((u8) layer->unk0 | 0x20); + goto block_119; + } + layer->unk0 = (s8) ((u8) layer->unk0 & 0xFFDF); + if (((u32) (sp68->unk0 << 6) >> 0x1F) == 1) { + temp_v1_8 = temp_v0_3 & 0xC0; + if (temp_v1_8 != 0) { + if (temp_v1_8 != 0x40) { + var_a0 = var_s3; + if (temp_v1_8 != 0x80) { + var_a2 = sp34; + } else { + temp_v1_9 = temp_s0->pc; + var_a2 = (s32) *temp_v1_9; + temp_s0->pc = temp_v1_9 + 1; + var_a0 = (u16) layer->playPercentage; + layer->noteDuration = temp_v1_9[1]; + temp_s0->pc += 1; + } } else { - temp_v1_9 = temp_s0->unk0; - temp_a2 = *temp_v1_9; - temp_t2 = temp_v1_9 + 1; - temp_s0->unk0 = temp_t2; - arg0->unk3 = *temp_t2; - temp_s0->unk0 = temp_s0->unk0 + 1; - phi_a2 = temp_a2; - phi_a0 = arg0->unk36; + temp_v0_12 = m64_read_compressed_u16(temp_s0); + temp_v1_10 = temp_s0->pc; + var_a0 = temp_v0_12 & 0xFFFF; + var_a2 = (s32) *temp_v1_10; + temp_s0->pc = temp_v1_10 + 1; + layer->noteDuration = 0; + layer->playPercentage = (s16) temp_v0_12; } } else { - temp_v0_12 = func_800BF14C(temp_s0, temp_v0_3); - temp_v1_10 = temp_s0->unk0; - temp_a0_3 = temp_v0_12 & 0xFFFF; - temp_a2_2 = *temp_v1_10; - temp_s0->unk0 = temp_v1_10 + 1; - arg0->unk3 = 0; - arg0->unk36 = temp_v0_12; - phi_a2 = temp_a2_2; - phi_a0 = temp_a0_3; + temp_v0_13 = m64_read_compressed_u16(temp_s0); + temp_v1_11 = temp_s0->pc; + var_a0 = temp_v0_13 & 0xFFFF; + var_a2 = (s32) *temp_v1_11; + temp_s0->pc = temp_v1_11 + 1; + layer->noteDuration = temp_v1_11[1]; + temp_s0->pc += 1; + layer->playPercentage = (s16) temp_v0_13; + } + if ((var_a2 >= 0x80) || (var_a2 < 0)) { + var_a2 = 0x0000007F; } + temp_f0 = (f32) var_a2; + var_s2_2 = (temp_s2 - (temp_s2 & 0xC0)) & 0xFF; + layer->velocitySquare = (temp_f0 * temp_f0) / 16129.0f; } else { - temp_v0_13 = func_800BF14C(temp_s0, temp_v0_3); - temp_v1_11 = temp_s0->unk0; - temp_a0_4 = temp_v0_13 & 0xFFFF; - temp_a2_3 = *temp_v1_11; - temp_t6_2 = temp_v1_11 + 1; - temp_s0->unk0 = temp_t6_2; - arg0->unk3 = *temp_t6_2; - temp_s0->unk0 = temp_s0->unk0 + 1; - arg0->unk36 = temp_v0_13; - phi_a2 = temp_a2_3; - phi_a0 = temp_a0_4; + switch (temp_v1_7) { /* switch 4; irregular */ + case 0x0: /* switch 4 */ + temp_v0_14 = m64_read_compressed_u16(temp_s0); + var_s3 = temp_v0_14 & 0xFFFF; + layer->playPercentage = (s16) temp_v0_14; + break; + case 0x40: /* switch 4 */ + var_s3 = (u16) layer->shortNoteDefaultPlayPercentage; + break; + case 0x80: /* switch 4 */ + var_s3 = (u16) layer->playPercentage; + break; + } + var_a0 = var_s3; + var_s2_2 = (temp_s2 - (temp_s2 & 0xC0)) & 0xFF; } - phi_a2_2 = phi_a2; - if ((phi_a2 >= 0x80) || (phi_a2 < 0)) { - phi_a2_2 = 0x7F; + layer->delay = (s16) var_a0; + layer->duration = (s16) ((s32) (layer->noteDuration * var_a0) >> 8); + if (((temp_s4->unk0 & 0x20000000) && (sp68->muteBehavior & 0x40)) || (temp_v1_12 = sp68->unk0, (temp_v1_12 & 0x10000000))) { + layer->unk0 = (s8) ((u8) layer->unk0 | 0x20); + goto block_119; } - temp_f0 = phi_a2_2; - arg0->unk28 = (temp_f0 * temp_f0) / 16129.0f; - phi_s2_2 = (temp_s2 - (temp_s2 & 0xC0)) & 0xFF; - } else { - if (temp_v1_7 != 0) { - if (temp_v1_7 != 0x40) { - if (temp_v1_7 != 0x80) { - - } else { - phi_s3 = arg0->unk36; - } - } else { - phi_s3 = arg0->unk34; + temp_a0_3 = layer->instOrWave; + var_v0 = temp_a0_3; + if (temp_a0_3 == 0xFF) { + if (temp_v1_12 & 0x08000000) { + var_v0 = (u8) sp68->instOrWave; + goto block_88; } } else { - temp_v0_14 = func_800BF14C(temp_s0, temp_v0_3); - temp_s3_6 = temp_v0_14 & 0xFFFF; - arg0->unk36 = temp_v0_14; - phi_s3 = temp_s3_6; - } - phi_a0 = phi_s3; - phi_s2_2 = (temp_s2 - (temp_s2 & 0xC0)) & 0xFF; - } - arg0->unk38 = phi_a0; - arg0->unk3A = (arg0->unk3 * phi_a0) >> 8; - if ((((temp_s4->unk0 * 4) < 0) && ((sp68->unk3 & 0x40) != 0)) || (temp_v1_12 = sp68->unk0, ((temp_v1_12 * 8) < 0))) { - arg0->unk0 = arg0->unk0 | 0x20; - goto block_119; - } - temp_a0_5 = arg0->unk1; - phi_v0 = temp_a0_5; - if (temp_a0_5 == 0xFF) { - if ((temp_v1_12 * 0x10) < 0) { - phi_v0 = sp68->unk1C; - goto block_88; - } - /* Duplicate return node #139. Try simplifying control flow for better match */ - return; - } block_88: - if (phi_v0 == 0) { - temp_v0_15 = func_800BC9F8(sp68->unk6, (phi_s2_2 + sp68->unk1E + arg0->unk22) & 0xFF); - temp_v1_13 = temp_v0_15 + 4; - if (temp_v0_15 == 0) { - arg0->unk0 = arg0->unk0 | 0x20; - arg0->unk3C = arg0->unk38; - return; - } - arg0->unk1C = temp_v0_15->unkC; - arg0->unk18 = temp_v0_15->unk0; - if ((arg0->unk0 << 6) >= 0) { - arg0->unk5 = temp_v0_15->unk1; - } - arg0->unk48 = temp_v1_13; - phi_f4 = temp_v1_13->unk4; - goto block_117; - } - temp_a1 = (phi_s2_2 + temp_s4->unkC + sp68->unk1E + arg0->unk22) & 0xFF; - if (temp_a1 >= 0x80) { - arg0->unk0 = arg0->unk0 | 0x20; - } else { - if (temp_a0_5 == 0xFF) { - phi_a0_2 = sp68->unk40; - } else { - phi_a0_2 = arg0->unk44; - } - if (arg0->unk8 != 0) { - temp_v0_16 = arg0->unk4; - phi_a2_3 = temp_v0_16; - if (temp_v0_16 < temp_a1) { - phi_a2_3 = temp_a1; + if (var_v0 == 0) { + temp_v0_15 = get_drum((s32) sp68->bankId, (var_s2_2 + sp68->transposition + layer->transposition) & 0xFF); + temp_v1_13 = temp_v0_15 + 4; + if (temp_v0_15 == NULL) { + layer->unk0 = (s8) ((u8) layer->unk0 | 0x20); + layer->delayUnused = layer->delay; + return; + } + layer->adsr.envelope = temp_v0_15->envelope; + layer->adsr.releaseRate = temp_v0_15->releaseRate; + if (!(layer->unk0 & 0x02000000)) { + layer->pan = temp_v0_15->pan; + } + layer->sound = temp_v1_13; + var_f4 = temp_v1_13->tuning; + goto block_117; } - if (phi_a0_2 != 0) { - temp_v0_17 = func_800BC90C(phi_a0_2, phi_a2_3, phi_a2_3); - sp44 = temp_v0_17 == arg0->unk48; - arg0->unk48 = temp_v0_17; - phi_f0 = temp_v0_17->unk4; + temp_a1 = (var_s2_2 + temp_s4->transposition + sp68->transposition + layer->transposition) & 0xFF; + if (temp_a1 >= 0x80) { + layer->unk0 = (s8) ((u8) layer->unk0 | 0x20); } else { - arg0->unk48 = NULL; - phi_f0 = 1.0f; - } - temp_f2 = gNoteFrequencies[temp_a1] * phi_f0; - temp_t4_2 = arg0->unk8 & ~0x80; - switch (temp_t4_2) { /* switch 3 */ - case 1: /* switch 3 */ - case 3: /* switch 3 */ - case 5: /* switch 3 */ - phi_f0_2 = gNoteFrequencies[arg0->unk4] * phi_f0; - break; - default: /* switch 3 */ - phi_f0_2 = temp_f2; - break; + if (temp_a0_3 == 0xFF) { + var_a0_2 = sp68->instrument; + } else { + var_a0_2 = layer->instrument; + } + if (layer->portamento.mode != 0) { + temp_v0_16 = layer->portamentoTargetNote; + var_a2_2 = temp_v0_16; + if ((s32) temp_v0_16 < temp_a1) { + var_a2_2 = (u8) temp_a1; + } + if (var_a0_2 != NULL) { + temp_v0_17 = instrument_get_audio_bank_sound(var_a0_2, (s32) var_a2_2); + sp44 = temp_v0_17 == (s32) layer->sound; + layer->sound = (struct AudioBankSound *) temp_v0_17; + var_f0 = temp_v0_17->unk4; + } else { + var_f0 = 1.0f; + layer->sound = NULL; + } + temp_f2 = gNoteFrequencies[temp_a1] * var_f0; + temp_t4_2 = layer->portamento.mode & ~0x80; + switch (temp_t4_2) { /* switch 3 */ + case 1: /* switch 3 */ + case 3: /* switch 3 */ + case 5: /* switch 3 */ + var_f0_2 = gNoteFrequencies[layer->portamentoTargetNote] * var_f0; + break; + default: /* switch 3 */ + case 2: /* switch 3 */ + case 4: /* switch 3 */ + var_f0_2 = temp_f2; + break; + } + temp_v0_18 = &layer->portamento; + temp_v0_18->extent = (temp_f2 / var_f0_2) - 1.0f; + if (layer->portamento.mode & 0x80) { + temp_v0_18->speed = ((f32) temp_s4->tempo * 32512.0f) / ((f32) layer->delay * (f32) D_803B70B4 * (f32) layer->portamentoTime); + } else { + temp_v0_18->speed = 127.0f / (f32) layer->portamentoTime; + } + temp_v0_18->cur = 0.0f; + layer->freqScale = var_f0_2; + if ((layer->portamento.mode & ~0x80) == 5) { + layer->portamentoTargetNote = (u8) temp_a1; + } + } else if (var_a0_2 != NULL) { + temp_v0_19 = instrument_get_audio_bank_sound(var_a0_2, temp_a1); + sp44 = temp_v0_19 == (s32) layer->sound; + layer->sound = (struct AudioBankSound *) temp_v0_19; + layer->freqScale = gNoteFrequencies[temp_a1] * temp_v0_19->unk4; + } else { + layer->sound = NULL; + var_f4 = gNoteFrequencies[temp_a1]; +block_117: + layer->freqScale = var_f4; + } } - temp_v0_18 = arg0 + 8; - temp_v0_18->unkC = (temp_f2 / phi_f0_2) - 1.0f; - if ((arg0->unk8 & 0x80) != 0) { - temp_v0_18->unk8 = (temp_s4->unk8 * 32512.0f) / (arg0->unk38 * D_803B70B4 * arg0->unk20); + layer->delayUnused = layer->delay; +block_119: + temp_v0_20 = layer->unk0; + if (((u32) (temp_v0_20 * 4) >> 0x1F) == 1) { + if ((layer->note != NULL) || (temp_v0_20 & 0x10000000)) { + seq_channel_layer_note_decay(layer); + } } else { - temp_v0_18->unk8 = 127.0f / arg0->unk20; - } - temp_v0_18->unk4 = 0.0f; - arg0->unk24 = phi_f0_2; - if ((arg0->unk8 & ~0x80) == 5) { - arg0->unk4 = temp_a1; + var_s2_3 = 0; + if (!(temp_v0_20 & 0x10000000)) { + var_s2_3 = 1; + } else { + temp_a0_4 = layer->note; + if ((temp_a0_4 == NULL) || (layer->status == 0)) { + var_s2_3 = 1; + } else if (sp44 == 0) { + seq_channel_layer_note_decay(layer); + var_s2_3 = 1; + } else if (layer != temp_a0_4->parentLayer) { + var_s2_3 = 1; + } else if (layer->sound == NULL) { + init_synthetic_wave(temp_a0_4, layer); + } + } + if (var_s2_3 != 0) { + layer->note = alloc_note(layer); + } + temp_a0_5 = layer->note; + if ((temp_a0_5 != NULL) && (layer == temp_a0_5->parentLayer)) { + note_vibrato_init(temp_a0_5); + } } - } else if (phi_a0_2 != 0) { - temp_v0_19 = func_800BC90C(phi_a0_2, temp_a1, MIPS2C_ERROR(Read from unset register $a2)); - sp44 = temp_v0_19 == arg0->unk48; - arg0->unk48 = temp_v0_19; - arg0->unk24 = gNoteFrequencies[temp_a1] * temp_v0_19->unk4; - } else { - arg0->unk48 = NULL; - phi_f4 = gNoteFrequencies[temp_a1]; -block_117: - arg0->unk24 = phi_f4; } } - arg0->unk3C = arg0->unk38; -block_119: - temp_v0_20 = arg0->unk0; - if (((temp_v0_20 * 4) >> 0x1F) == 1) { - if ((arg0->unk40 != 0) || ((temp_v0_20 * 8) < 0)) { - func_800BD120(arg0); - return; - } - /* Duplicate return node #139. Try simplifying control flow for better match */ - return; - } - phi_s2_3 = 0; - if ((temp_v0_20 * 8) >= 0) { - phi_s2_3 = 1; - } else { - temp_a0_6 = arg0->unk40; - if ((temp_a0_6 == 0) || (arg0->unk2 == 0)) { - phi_s2_3 = 1; - } else if (sp44 == 0) { - func_800BD120(arg0); - phi_s2_3 = 1; - } else if (arg0 != temp_a0_6->unk44) { - phi_s2_3 = 1; - } else if (arg0->unk48 == 0) { - func_800BD264(temp_a0_6, arg0); - } - } - if (phi_s2_3 != 0) { - arg0->unk40 = func_800BDA44(arg0); - } - temp_a0_7 = arg0->unk40; - if ((temp_a0_7 != 0) && (arg0 == temp_a0_7->unk44)) { - func_800BE4D4(temp_a0_7); - } - /* Duplicate return node #139. Try simplifying control flow for better match */ } } } #else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BF190.s") +GLOBAL_ASM("asm/non_matchings/audio/seqplayer/seq_channel_layer_process_script.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void *func_800BC948(u8, u8); // extern - -s32 func_800BFC68(void *arg0, u8 arg1, void **arg2, void *arg3) { - void *temp_v0; - - temp_v0 = func_800BC948(arg0->unk6, arg1); - if (temp_v0 == 0) { - *arg2 = NULL; +u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, struct AdsrSettings *adsr) { + struct Instrument *inst; + inst = get_instrument_inner(seqChannel->bankId, instId); + if (inst == NULL) { + *instOut = NULL; return 0; } - arg3->unk4 = temp_v0->unk4; - arg3->unk0 = temp_v0->unk3; - *arg2 = temp_v0; - return (arg1 + 1) & 0xFF; + adsr->envelope = inst->envelope; + adsr->releaseRate = inst->releaseRate; + *instOut = inst; + instId++; + return instId; } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BFC68.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s16 func_800BFC68(s32, void *, void *); // extern -void func_800BFCD8(u8 *arg0, s32 arg1) { - s16 temp_v0; - s32 temp_t6; - - temp_t6 = arg1 & 0xFF; - if (temp_t6 >= 0x80) { - arg0->unk1C = temp_t6; - arg0->unk40 = 0; - goto block_6; - } - if (temp_t6 == 0x7F) { - arg0->unk1C = 0; - arg0->unk40 = 1; - goto block_6; - } - temp_v0 = func_800BFC68(temp_t6, arg0 + 0x40, arg0 + 0x7C); - arg0->unk1C = temp_v0; - if (temp_v0 == 0) { - arg0->unk0 = arg0->unk0 & 0xFFF7; - return; +void set_instrument(struct SequenceChannel *seqChannel, u8 instId) { + if (instId >= 0x80) { + seqChannel->instOrWave = instId; + seqChannel->instrument = NULL; + } else if (instId == 0x7f) { + seqChannel->instOrWave = 0; + seqChannel->instrument = (struct Instrument *) 1; + } else { + if ((seqChannel->instOrWave = get_instrument(seqChannel, instId, &seqChannel->instrument, &seqChannel->adsr)) == 0) + { + seqChannel->hasInstrument = FALSE; + return; + } } -block_6: - arg0->unk0 = arg0->unk0 | 8; + seqChannel->hasInstrument = TRUE; } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BFCD8.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BFD6C(void *arg0, s32 arg1) { - arg0->unk24 = (arg1 & 0xFF) / 127.0f; +void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume) { + seqChannel->volume = FLOAT_CAST(volume) / US_FLOAT(127.0); } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BFD6C.s") -#endif #ifdef MIPS_TO_C -//generated by mips_to_c commit bd0364fa19633bd6201f8007e2d0a7ed87825909 -s32 func_800B9A90(?, ?, u8, u16); /* extern */ -void func_800BD418(void *); /* extern */ -void func_800BD578(void *, s32); /* extern */ -void func_800BEB54(void *, s32); /* extern */ -void func_800BEBA4(void *); /* extern */ -void func_800BEE88(s32 *, s32, s32); /* extern */ -void func_800BF190(s32); /* extern */ -void func_800BFCD8(void *, s32); /* extern */ -void func_800BFD6C(void *, s32); /* extern */ +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +? seq_channel_layer_process_script(struct SequenceChannelLayer *); /* extern */ +extern s32 gAlBankSets; -void func_800BFD90(void *arg0) { +void func_800BFD90(struct SequenceChannel *seqChannel) { u8 sp55; - u16 sp52; + s16 sp52; s32 sp34; f32 temp_f18; f32 temp_f6; f32 temp_f8; - s16 temp_v1_5; - s32 *temp_s4; - s32 *temp_v1_10; - s32 temp_a0; + s16 temp_v0_4; + s16 temp_v0_8; s32 temp_a0_4; - s32 temp_a0_5; + s32 temp_a1; s32 temp_a1_2; - s32 temp_a1_3; s32 temp_s0; - s32 temp_s0_2; - s32 temp_s0_6; - s32 temp_s0_7; + s32 temp_s0_5; s32 temp_t3; s32 temp_v0_2; - s32 temp_v1_11; s32 temp_v1_3; - s32 temp_v1_6; - s8 *temp_v0_4; - s8 temp_s3; - s8 temp_v0_5; - s8 temp_v1_4; + s32 temp_v1_5; + s32 temp_v1_9; + s32 var_s0; + s32 var_s0_2; + s8 var_s3; + struct M64ScriptState *temp_s1; + struct NotePool *temp_s0_2; + struct SequenceChannel *var_s1; + struct SequenceChannel *var_s1_2; + struct SequenceChannelLayer *temp_a0; + struct SequenceChannelLayer *temp_a0_5; + struct SequenceChannelLayer *temp_v1_8; + struct SequencePlayer *temp_s4; u16 temp_a3; u16 temp_a3_2; u16 temp_t5; - u16 temp_v0_6; u16 temp_v1; + u16 temp_v1_4; + u16 var_v0; u32 temp_t6; u32 temp_v0; - u8 *temp_v1_8; + u8 *temp_v0_6; + u8 *temp_v1_7; u8 temp_a0_2; u8 temp_a0_3; + u8 temp_s0_3; u8 temp_s0_4; - u8 temp_s0_5; u8 temp_t0; u8 temp_t7; - void *temp_a1; - void *temp_s0_3; - void *temp_s1; + u8 temp_v0_5; + u8 temp_v0_7; void *temp_v0_3; - void *temp_v1_12; + void *temp_v1_10; void *temp_v1_2; - void *temp_v1_7; - void *temp_v1_9; - void *phi_s1; - s32 phi_s0; - u16 phi_v0; - s32 phi_s3; - void *phi_s1_2; - s32 phi_s0_2; + void *temp_v1_6; - temp_v0 = arg0->unk0; + temp_v0 = seqChannel->unk0; if ((temp_v0 >> 0x1F) != 0) { - phi_s0 = 0; - phi_s0_2 = 0; - if ((temp_v0 * 4) < 0) { - phi_s1 = arg0; + var_s0 = 0; + if (temp_v0 & 0x20000000) { + var_s1 = seqChannel; do { - temp_a0 = phi_s1->unk48; - if (temp_a0 != 0) { - func_800BF190(temp_a0); + temp_a0 = var_s1->layers[0]; + if (temp_a0 != NULL) { + seq_channel_layer_process_script(temp_a0); } - temp_s0 = phi_s0 + 4; - phi_s1 += 4; - phi_s0 = temp_s0; - } while (temp_s0 != 0x10); + var_s0 += 4; + var_s1 += 4; + } while (var_s0 != 0x10); return; } - temp_s4 = arg0->unk44; - if (((temp_s4->unk0 * 4) >= 0) || ((arg0->unk3 & 0x80) == 0)) { - temp_v1 = arg0->unk1A; - temp_s1 = arg0 + 0x60; - phi_v0 = temp_v1; + temp_s4 = seqChannel->seqPlayer; + if (!(temp_s4->unk0 & 0x20000000) || !(seqChannel->muteBehavior & 0x80)) { + temp_v1 = seqChannel->delay; + temp_s1 = &seqChannel->scriptState; + var_v0 = temp_v1; if (temp_v1 != 0) { temp_t5 = temp_v1 - 1; - arg0->unk1A = temp_t5; - phi_v0 = temp_t5 & 0xFFFF; + seqChannel->delay = temp_t5; + var_v0 = temp_t5 & 0xFFFF; } - phi_s3 = sp4B; - if (phi_v0 == 0) { + var_s3 = sp4B; + if (var_v0 == 0) { + case 0xCD: /* switch 3 */ + case 0xCE: /* switch 3 */ + case 0xCF: /* switch 3 */ + case 0xD5: /* switch 3 */ + case 0xD6: /* switch 3 */ + case 0xED: /* switch 3 */ + case 0xEE: /* switch 3 */ default: /* switch 2 */ - default: /* switch 1 */ loop_12: - temp_v0_2 = func_800BF108(temp_s1); - temp_s0_2 = temp_v0_2 & 0xFF; - if (temp_v0_2 >= 0xC1) { - switch (temp_v0_2) { /* switch 1 */ - case 0xFF: /* switch 1 */ - temp_a0_2 = temp_s1->unk18; - if (temp_a0_2 == 0) { - func_800BEBA4(arg0); - } else { - temp_t7 = (temp_a0_2 - 1) & 0xFF; - temp_s1->unk18 = temp_t7; - temp_s1->unk0 = (temp_s1 + (temp_t7 * 4))->unk4; - goto loop_12; - } - break; - case 0xFD: /* switch 1 */ - arg0->unk1A = func_800BF14C(temp_s1); - break; - case 0xEA: /* switch 1 */ - arg0->unk0 = arg0->unk0 | 0x20; - break; - case 0xFC: /* switch 1 */ - temp_t3 = func_800BF11C(temp_s1) & 0xFFFF; - (temp_s1 + (temp_s1->unk18 * 4))->unk4 = temp_s1->unk0; - temp_s1->unk18 = temp_s1->unk18 + 1; - temp_s1->unk0 = temp_s4->unk14 + temp_t3; - goto loop_12; - case 0xF8: /* switch 1 */ - (temp_s1 + temp_s1->unk18)->unk14 = func_800BF108(temp_s1); - (temp_s1 + (temp_s1->unk18 * 4))->unk4 = temp_s1->unk0; - temp_s1->unk18 = temp_s1->unk18 + 1; - goto loop_12; - case 0xF7: /* switch 1 */ - temp_v0_3 = temp_s1 + temp_s1->unk18; - temp_v0_3->unk13 = temp_v0_3->unk13 - 1; - temp_a0_3 = temp_s1->unk18; - if ((temp_s1 + temp_a0_3)->unk13 != 0) { - temp_s1->unk0 = *(temp_s1 + (temp_a0_3 * 4)); - } else { - temp_s1->unk18 = temp_a0_3 - 1; - } - goto loop_12; - case 0xF6: /* switch 1 */ - temp_s1->unk18 = temp_s1->unk18 - 1; - goto loop_12; - case 0xF5: /* switch 1 */ - case 0xF9: /* switch 1 */ - case 0xFA: /* switch 1 */ - case 0xFB: /* switch 1 */ - if (((temp_s0_2 != 0xFA) || (phi_s3 == 0)) && ((temp_s0_2 != 0xF9) || (phi_s3 < 0)) && ((temp_s0_2 != 0xF5) || (phi_s3 >= 0))) { - temp_s1->unk0 = temp_s4->unk14 + (func_800BF11C(temp_s1) & 0xFFFF); - } - goto loop_12; - case 0xF2: /* switch 1 */ - case 0xF3: /* switch 1 */ - case 0xF4: /* switch 1 */ - if (((temp_s0_2 != 0xF3) || (phi_s3 == 0)) && ((temp_s0_2 != 0xF2) || (phi_s3 < 0))) { - temp_s1->unk0 = temp_s1->unk0 + func_800BF108(temp_s1); - } - goto loop_12; - case 0xF1: /* switch 1 */ - temp_s0_3 = arg0 + 0x84; - func_800BD418(temp_s0_3); - func_800BD578(temp_s0_3, func_800BF108(temp_s1)); - goto loop_12; - case 0xF0: /* switch 1 */ - func_800BD418(arg0 + 0x84); - goto loop_12; - case 0xC2: /* switch 1 */ - arg0->unk34 = temp_s4->unk14 + (func_800BF11C(temp_s1) & 0xFFFF); - goto loop_12; - case 0xC5: /* switch 1 */ - if (phi_s3 != -1) { - temp_v1_2 = arg0->unk34 + (phi_s3 * 2); - arg0->unk34 = temp_s4->unk14 + ((temp_v1_2->unk1 + (temp_v1_2->unk0 << 8)) & 0xFFFF); - } - goto loop_12; - case 0xEB: /* switch 1 */ - temp_v1_3 = D_803B7078; - temp_a3 = *(temp_v1_3 + (temp_s4->unk4 * 2)); - temp_s0_4 = *(((temp_a3 + *(temp_a3 + temp_v1_3)) - func_800BF108(temp_s1)) + temp_v1_3); - if (func_800B9A90(1, 2, temp_s0_4, temp_a3) != 0) { - arg0->unk6 = temp_s0_4; - } - /* fallthrough */ - case 0xC1: /* switch 1 */ - func_800BFCD8(arg0, func_800BF108(temp_s1) & 0xFF); - goto loop_12; - case 0xC3: /* switch 1 */ - arg0->unk0 = arg0->unk0 & 0xFFFD; - goto loop_12; - case 0xC4: /* switch 1 */ - arg0->unk0 = arg0->unk0 | 2; - goto loop_12; - case 0xDF: /* switch 1 */ - func_800BFD6C(arg0, func_800BF108(temp_s1) & 0xFF); - arg0->unk1 = arg0->unk1 | 0x40; - goto loop_12; - case 0xE0: /* switch 1 */ - temp_f6 = func_800BF108(temp_s1); - arg0->unk1 = arg0->unk1 | 0x40; - arg0->unk20 = temp_f6 * 0.0078125f; - goto loop_12; - case 0xDE: /* switch 1 */ - temp_f18 = func_800BF11C(temp_s1) & 0xFFFF; - arg0->unk1 = arg0->unk1 | 0x80; - arg0->unk30 = temp_f18 / 32768.0f; - goto loop_12; - case 0xD3: /* switch 1 */ - temp_f8 = gPitchBendFrequencyScale[(func_800BF108(temp_s1) + 0x7F) & 0xFF]; - arg0->unk1 = arg0->unk1 | 0x80; - arg0->unk30 = temp_f8; - goto loop_12; - case 0xDD: /* switch 1 */ - arg0->unk9 = func_800BF108(temp_s1); - arg0->unk1 = arg0->unk1 | 0x20; - goto loop_12; - case 0xDC: /* switch 1 */ - arg0->unkA = func_800BF108(temp_s1); - arg0->unk1 = arg0->unk1 | 0x20; - goto loop_12; - case 0xDB: /* switch 1 */ - temp_v0_4 = temp_s1->unk0; - temp_v1_4 = *temp_v0_4; - temp_s1->unk0 = temp_v0_4 + 1; - arg0->unk1E = temp_v1_4; - goto loop_12; - case 0xDA: /* switch 1 */ - arg0->unk80 = temp_s4->unk14 + (func_800BF11C(temp_s1) & 0xFFFF); - goto loop_12; - case 0xD9: /* switch 1 */ - arg0->unk7C = func_800BF108(temp_s1); - goto loop_12; - case 0xD8: /* switch 1 */ - arg0->unk12 = func_800BF108(temp_s1) * 8; - arg0->unkE = 0; - arg0->unk16 = 0; - goto loop_12; - case 0xD7: /* switch 1 */ - temp_v1_5 = func_800BF108(temp_s1) << 5; - arg0->unk10 = temp_v1_5; - arg0->unkC = temp_v1_5; - arg0->unk14 = 0; - goto loop_12; - case 0xE2: /* switch 1 */ - arg0->unkE = func_800BF108(temp_s1) * 8; - arg0->unk12 = func_800BF108(temp_s1) * 8; - arg0->unk16 = func_800BF108(temp_s1) * 0x10; - goto loop_12; - case 0xE1: /* switch 1 */ - arg0->unkC = func_800BF108(temp_s1) << 5; - arg0->unk10 = func_800BF108(temp_s1) << 5; - arg0->unk14 = func_800BF108(temp_s1) * 0x10; - goto loop_12; - case 0xE3: /* switch 1 */ - arg0->unk18 = func_800BF108(temp_s1) * 0x10; - goto loop_12; - case 0xD4: /* switch 1 */ - arg0->unk4 = func_800BF108(temp_s1); - goto loop_12; - case 0xC6: /* switch 1 */ - temp_v1_6 = D_803B7078; - temp_a3_2 = *(temp_v1_6 + (temp_s4->unk4 * 2)); - temp_s0_5 = *(((temp_a3_2 + *(temp_a3_2 + temp_v1_6)) - func_800BF108(temp_s1)) + temp_v1_6); - if (func_800B9A90(1, 2, temp_s0_5, temp_a3_2) != 0) { - arg0->unk6 = temp_s0_5; - } - goto loop_12; - case 0xC7: /* switch 1 */ - sp34 = phi_s3 & 0xFF; - temp_s0_6 = func_800BF108(temp_s1) & 0xFF; - *(temp_s4->unk14 + (func_800BF11C(temp_s1) & 0xFFFF)) = sp34 + temp_s0_6; - goto loop_12; - case 0xC8: /* switch 1 */ - case 0xC9: /* switch 1 */ - case 0xCC: /* switch 1 */ - temp_v0_5 = func_800BF108(temp_s1); - if (temp_s0_2 == 0xC8) { - phi_s3 = phi_s3 - temp_v0_5; - } else if (temp_s0_2 == 0xCC) { - phi_s3 = temp_v0_5; - } else { - phi_s3 = phi_s3 & temp_v0_5; - } - goto loop_12; - case 0xCA: /* switch 1 */ - arg0->unk3 = func_800BF108(temp_s1); - goto loop_12; - case 0xCB: /* switch 1 */ - phi_s3 = *(temp_s4->unk14 + ((func_800BF11C(temp_s1) & 0xFFFF) + phi_s3)); - goto loop_12; - case 0xD0: /* switch 1 */ - arg0->unk0 = ((func_800BF108(temp_s1) * 4) & 4) | (arg0->unk0 & 0xFFFB); - goto loop_12; - case 0xD1: /* switch 1 */ - arg0->unk2 = func_800BF108(temp_s1); - goto loop_12; - case 0xD2: /* switch 1 */ - arg0->unk7D = func_800BF108(temp_s1); - goto loop_12; - case 0xE5: /* switch 1 */ - arg0->unk7 = func_800BF108(temp_s1); - goto loop_12; - case 0xE4: /* switch 1 */ - if (phi_s3 != -1) { - (temp_s1 + (temp_s1->unk18 * 4))->unk4 = temp_s1->unk0; - temp_v1_7 = arg0->unk34 + (phi_s3 * 2); - temp_s1->unk18 = temp_s1->unk18 + 1; - temp_s1->unk0 = temp_s4->unk14 + ((temp_v1_7->unk1 + (temp_v1_7->unk0 << 8)) & 0xFFFF); - } - goto loop_12; - case 0xE6: /* switch 1 */ - arg0->unk8 = func_800BF108(temp_s1); - goto loop_12; - case 0xE7: /* switch 1 */ - temp_v1_8 = temp_s4->unk14 + (func_800BF11C(temp_s1) & 0xFFFF); - temp_v1_9 = temp_v1_8 + 7; - arg0->unk3 = *temp_v1_8; - arg0->unk2 = temp_v1_9->unk-6; - arg0->unk5 = temp_v1_9->unk-5; - arg0->unk1E = temp_v1_9->unk-4; - arg0->unk9 = temp_v1_9->unk-3; - arg0->unkA = temp_v1_9->unk-2; - arg0->unk4 = temp_v1_9->unk-1; - arg0->unk1 = arg0->unk1 | 0x20; - arg0->unk7 = temp_v1_9->unk0; - goto loop_12; - case 0xE8: /* switch 1 */ - arg0->unk3 = func_800BF108(temp_s1); - arg0->unk2 = func_800BF108(temp_s1); - arg0->unk5 = func_800BF108(temp_s1); - arg0->unk1E = func_800BF108(temp_s1); - arg0->unk9 = func_800BF108(temp_s1); - arg0->unkA = func_800BF108(temp_s1); - arg0->unk4 = func_800BF108(temp_s1); - arg0->unk7 = func_800BF108(temp_s1); - arg0->unk1 = arg0->unk1 | 0x20; - goto loop_12; - case 0xEC: /* switch 1 */ - arg0->unk12 = 0; - arg0->unkE = 0; - arg0->unk16 = 0; - arg0->unk10 = 0; - arg0->unkC = 0; - arg0->unk14 = 0; - arg0->unk30 = 1.0f; - goto loop_12; - case 0xE9: /* switch 1 */ - arg0->unk5 = func_800BF108(temp_s1); - goto loop_12; - case 0xEF: /* switch 1 */ - func_800BF11C(temp_s1); - func_800BF108(temp_s1); + temp_v0_2 = m64_read_u8(temp_s1); + temp_s0 = temp_v0_2 & 0xFF; + switch (temp_v0_2) { /* switch 3; irregular */ + case 0xFF: /* switch 3 */ + temp_a0_2 = temp_s1->depth; + if (temp_a0_2 == 0) { + sequence_channel_disable(seqChannel); + } else { + temp_t7 = (temp_a0_2 - 1) & 0xFF; + temp_s1->depth = temp_t7; + temp_s1->pc = temp_s1->stack[temp_t7]; goto loop_12; } - } else { + break; + case 0xFD: /* switch 3 */ + seqChannel->delay = m64_read_compressed_u16(temp_s1); + break; + case 0xEA: /* switch 3 */ + seqChannel->unk0 = (s8) ((u8) seqChannel->unk0 | 0x20); + break; + case 0xFC: /* switch 3 */ + temp_t3 = m64_read_s16(temp_s1) & 0xFFFF; + temp_s1->stack[temp_s1->depth] = temp_s1->pc; + temp_s1->depth += 1; + temp_s1->pc = &temp_s4->seqData[temp_t3]; + goto loop_12; + case 0xF8: /* switch 3 */ + temp_s1->remLoopIters[temp_s1->depth] = m64_read_u8(temp_s1); + temp_s1->stack[temp_s1->depth] = temp_s1->pc; + temp_s1->depth += 1; + goto loop_12; + case 0xF7: /* switch 3 */ + temp_v0_3 = temp_s1 + temp_s1->depth; + temp_v0_3->unk13 = (u8) (temp_v0_3->unk13 - 1); + temp_a0_3 = temp_s1->depth; + if ((temp_s1 + temp_a0_3)->unk13 != 0) { + temp_s1->pc = *(temp_s1 + (temp_a0_3 * 4)); + } else { + temp_s1->depth = temp_a0_3 - 1; + } + goto loop_12; + case 0xF6: /* switch 3 */ + temp_s1->depth -= 1; + goto loop_12; + case 0xF5: /* switch 3 */ + case 0xF9: /* switch 3 */ + case 0xFA: /* switch 3 */ + case 0xFB: /* switch 3 */ + temp_v0_4 = m64_read_s16(temp_s1); + if (((temp_s0 != 0xFA) || (var_s3 == 0)) && ((temp_s0 != 0xF9) || (var_s3 < 0)) && ((temp_s0 != 0xF5) || (var_s3 >= 0))) { + temp_s1->pc = &temp_s4->seqData[temp_v0_4 & 0xFFFF]; + } + goto loop_12; + case 0xF2: /* switch 3 */ + case 0xF3: /* switch 3 */ + case 0xF4: /* switch 3 */ + temp_v0_5 = m64_read_u8(temp_s1); + if (((temp_s0 != 0xF3) || (var_s3 == 0)) && ((temp_s0 != 0xF2) || (var_s3 < 0))) { + temp_s1->pc = &temp_s1->pc[(s8) temp_v0_5]; + } + goto loop_12; + case 0xF1: /* switch 3 */ + temp_s0_2 = &seqChannel->notePool; + note_pool_clear(temp_s0_2); + note_pool_fill(temp_s0_2, m64_read_u8(temp_s1)); + goto loop_12; + case 0xF0: /* switch 3 */ + note_pool_clear(&seqChannel->notePool); + goto loop_12; + case 0xC2: /* switch 3 */ + seqChannel->dynTable = (u8 (*)[][2]) &temp_s4->seqData[m64_read_s16(temp_s1) & 0xFFFF]; + goto loop_12; + case 0xC5: /* switch 3 */ + if (var_s3 != -1) { + temp_v1_2 = seqChannel->dynTable + (var_s3 * 2); + seqChannel->dynTable = (u8 (*)[][2]) &temp_s4->seqData[(temp_v1_2->unk1 + (temp_v1_2->unk0 << 8)) & 0xFFFF]; + } + goto loop_12; + case 0xEB: /* switch 3 */ + temp_v1_3 = gAlBankSets; + temp_a3 = *(temp_v1_3 + (temp_s4->seqId * 2)); + temp_s0_3 = *(((temp_a3 + *(temp_a3 + temp_v1_3)) - m64_read_u8(temp_s1)) + temp_v1_3); + if (get_bank_or_seq(1, 2, (s32) temp_s0_3) != NULL) { + seqChannel->bankId = temp_s0_3; + } + /* fallthrough */ + case 0xC1: /* switch 3 */ + set_instrument(seqChannel, m64_read_u8(temp_s1) & 0xFF); + goto loop_12; + case 0xC3: /* switch 3 */ + seqChannel->unk0 = (s8) ((u8) seqChannel->unk0 & 0xFFFD); + goto loop_12; + case 0xC4: /* switch 3 */ + seqChannel->unk0 = (s8) ((u8) seqChannel->unk0 | 2); + goto loop_12; + case 0xDF: /* switch 3 */ + sequence_channel_set_volume(seqChannel, m64_read_u8(temp_s1) & 0xFF); + seqChannel->changes.as_u8 |= 0x40; + goto loop_12; + case 0xE0: /* switch 3 */ + temp_f6 = (f32) m64_read_u8(temp_s1); + seqChannel->changes.as_u8 |= 0x40; + seqChannel->volumeScale = temp_f6 * 0.0078125f; + goto loop_12; + case 0xDE: /* switch 3 */ + temp_f18 = (f32) (m64_read_s16(temp_s1) & 0xFFFF); + seqChannel->changes.as_u8 |= 0x80; + seqChannel->freqScale = temp_f18 / 32768.0f; + goto loop_12; + case 0xD3: /* switch 3 */ + temp_f8 = gPitchBendFrequencyScale[(m64_read_u8(temp_s1) + 0x7F) & 0xFF]; + seqChannel->changes.as_u8 |= 0x80; + seqChannel->freqScale = temp_f8; + goto loop_12; + case 0xDD: /* switch 3 */ + seqChannel->newPan = m64_read_u8(temp_s1); + seqChannel->changes.as_u8 |= 0x20; + goto loop_12; + case 0xDC: /* switch 3 */ + seqChannel->panChannelWeight = m64_read_u8(temp_s1); + seqChannel->changes.as_u8 |= 0x20; + goto loop_12; + case 0xDB: /* switch 3 */ + temp_v0_6 = temp_s1->pc; + temp_s1->pc = temp_v0_6 + 1; + seqChannel->transposition = (s16) (s8) *temp_v0_6; + goto loop_12; + case 0xDA: /* switch 3 */ + seqChannel->adsr.envelope = (struct AdsrEnvelope *) &temp_s4->seqData[m64_read_s16(temp_s1) & 0xFFFF]; + goto loop_12; + case 0xD9: /* switch 3 */ + seqChannel->adsr.releaseRate = m64_read_u8(temp_s1); + goto loop_12; + case 0xD8: /* switch 3 */ + seqChannel->vibratoExtentTarget = m64_read_u8(temp_s1) * 8; + seqChannel->vibratoExtentStart = 0; + seqChannel->vibratoExtentChangeDelay = 0; + goto loop_12; + case 0xD7: /* switch 3 */ + temp_v1_4 = m64_read_u8(temp_s1) << 5; + seqChannel->vibratoRateTarget = temp_v1_4; + seqChannel->vibratoRateStart = temp_v1_4; + seqChannel->vibratoRateChangeDelay = 0; + goto loop_12; + case 0xE2: /* switch 3 */ + seqChannel->vibratoExtentStart = m64_read_u8(temp_s1) * 8; + seqChannel->vibratoExtentTarget = m64_read_u8(temp_s1) * 8; + seqChannel->vibratoExtentChangeDelay = m64_read_u8(temp_s1) * 0x10; + goto loop_12; + case 0xE1: /* switch 3 */ + seqChannel->vibratoRateStart = m64_read_u8(temp_s1) << 5; + seqChannel->vibratoRateTarget = m64_read_u8(temp_s1) << 5; + seqChannel->vibratoRateChangeDelay = m64_read_u8(temp_s1) * 0x10; + goto loop_12; + case 0xE3: /* switch 3 */ + seqChannel->vibratoDelay = m64_read_u8(temp_s1) * 0x10; + goto loop_12; + case 0xD4: /* switch 3 */ + seqChannel->reverbVol = m64_read_u8(temp_s1); + goto loop_12; + case 0xC6: /* switch 3 */ + temp_v1_5 = gAlBankSets; + temp_a3_2 = *(temp_v1_5 + (temp_s4->seqId * 2)); + temp_s0_4 = *(((temp_a3_2 + *(temp_a3_2 + temp_v1_5)) - m64_read_u8(temp_s1)) + temp_v1_5); + if (get_bank_or_seq(1, 2, (s32) temp_s0_4) != NULL) { + seqChannel->bankId = temp_s0_4; + } + goto loop_12; + case 0xC7: /* switch 3 */ + sp34 = var_s3 & 0xFF; + temp_s0_5 = m64_read_u8(temp_s1) & 0xFF; + temp_s4->seqData[m64_read_s16(temp_s1) & 0xFFFF] = sp34 + temp_s0_5; + goto loop_12; + case 0xC8: /* switch 3 */ + case 0xC9: /* switch 3 */ + case 0xCC: /* switch 3 */ + temp_v0_7 = m64_read_u8(temp_s1); + if (temp_s0 == 0xC8) { + var_s3 -= temp_v0_7; + } else if (temp_s0 == 0xCC) { + var_s3 = (s8) temp_v0_7; + } else { + var_s3 &= temp_v0_7; + } + goto loop_12; + case 0xCA: /* switch 3 */ + seqChannel->muteBehavior = m64_read_u8(temp_s1); + goto loop_12; + case 0xCB: /* switch 3 */ + var_s3 = (s8) temp_s4->seqData[(m64_read_s16(temp_s1) & 0xFFFF) + var_s3]; + goto loop_12; + case 0xD0: /* switch 3 */ + seqChannel->unk0 = (s8) (((m64_read_u8(temp_s1) * 4) & 4) | ((u8) seqChannel->unk0 & 0xFFFB)); + goto loop_12; + case 0xD1: /* switch 3 */ + seqChannel->noteAllocPolicy = m64_read_u8(temp_s1); + goto loop_12; + case 0xD2: /* switch 3 */ + seqChannel->adsr.sustain = m64_read_u8(temp_s1); + goto loop_12; + case 0xE5: /* switch 3 */ + seqChannel->reverbIndex = m64_read_u8(temp_s1); + goto loop_12; + case 0xE4: /* switch 3 */ + if (var_s3 != -1) { + temp_s1->stack[temp_s1->depth] = temp_s1->pc; + temp_v1_6 = seqChannel->dynTable + (var_s3 * 2); + temp_s1->depth += 1; + temp_s1->pc = &temp_s4->seqData[(temp_v1_6->unk1 + (temp_v1_6->unk0 << 8)) & 0xFFFF]; + } + goto loop_12; + case 0xE6: /* switch 3 */ + seqChannel->bookOffset = m64_read_u8(temp_s1); + goto loop_12; + case 0xE7: /* switch 3 */ + temp_v1_7 = &temp_s4->seqData[m64_read_s16(temp_s1) & 0xFFFF]; + seqChannel->muteBehavior = *temp_v1_7; + seqChannel->noteAllocPolicy = temp_v1_7[7].unk-6; + seqChannel->notePriority = temp_v1_7[7].unk-5; + seqChannel->transposition = (s16) temp_v1_7[7].unk-4; + seqChannel->newPan = temp_v1_7[7].unk-3; + seqChannel->panChannelWeight = temp_v1_7[7].unk-2; + seqChannel->reverbVol = temp_v1_7[7].unk-1; + seqChannel->changes.as_u8 |= 0x20; + seqChannel->reverbIndex = temp_v1_7[7]; + goto loop_12; + case 0xE8: /* switch 3 */ + seqChannel->muteBehavior = m64_read_u8(temp_s1); + seqChannel->noteAllocPolicy = m64_read_u8(temp_s1); + seqChannel->notePriority = m64_read_u8(temp_s1); + seqChannel->transposition = (s16) m64_read_u8(temp_s1); + seqChannel->newPan = m64_read_u8(temp_s1); + seqChannel->panChannelWeight = m64_read_u8(temp_s1); + seqChannel->reverbVol = m64_read_u8(temp_s1); + seqChannel->reverbIndex = m64_read_u8(temp_s1); + seqChannel->changes.as_u8 |= 0x20; + goto loop_12; + case 0xEC: /* switch 3 */ + seqChannel->vibratoExtentTarget = 0; + seqChannel->vibratoExtentStart = 0; + seqChannel->vibratoExtentChangeDelay = 0; + seqChannel->vibratoRateTarget = 0; + seqChannel->vibratoRateStart = 0; + seqChannel->vibratoRateChangeDelay = 0; + seqChannel->freqScale = 1.0f; + goto loop_12; + case 0xE9: /* switch 3 */ + seqChannel->notePriority = m64_read_u8(temp_s1); + goto loop_12; + case 0xEF: /* switch 3 */ + m64_read_s16(temp_s1); + m64_read_u8(temp_s1); + goto loop_12; + default: /* switch 3 */ temp_t6 = temp_v0_2 & 0xF0; temp_a0_4 = temp_v0_2 & 0xF; temp_t0 = temp_a0_4 & 0xFF; switch (temp_t6) { /* switch 2 */ case 0x0: /* switch 2 */ - temp_v1_10 = (arg0 + ((temp_a0_4 & 0xFF) * 4))->unk48; - if (temp_v1_10 != 0) { - phi_s3 = (*temp_v1_10 * 2) >> 0x1F; + temp_v1_8 = seqChannel->layers[temp_a0_4 & 0xFF]; + if (temp_v1_8 != NULL) { + var_s3 = (s8) ((u32) (*temp_v1_8 * 2) >> 0x1F); } else { - phi_s3 = -1; + var_s3 = -1; } goto loop_12; case 0x70: /* switch 2 */ - (arg0 + (temp_a0_4 & 0xFF))->unk58 = phi_s3; + seqChannel->soundScriptIO[temp_a0_4 & 0xFF] = var_s3; goto loop_12; case 0x80: /* switch 2 */ - temp_v1_11 = temp_a0_4 & 0xFF; - temp_a1 = arg0 + temp_v1_11; - temp_s3 = temp_a1->unk58; - phi_s3 = temp_s3; - if (temp_v1_11 < 4) { - temp_a1->unk58 = -1; + temp_v1_9 = temp_a0_4 & 0xFF; + var_s3 = seqChannel->soundScriptIO[temp_v1_9]; + if (temp_v1_9 < 4) { + seqChannel->soundScriptIO[temp_v1_9] = -1; } goto loop_12; case 0x50: /* switch 2 */ - phi_s3 = phi_s3 - (arg0 + (temp_a0_4 & 0xFF))->unk58; + var_s3 -= seqChannel->soundScriptIO[temp_a0_4 & 0xFF]; goto loop_12; case 0x60: /* switch 2 */ - arg0->unk1A = temp_a0_4 & 0xFF; + seqChannel->delay = temp_a0_4 & 0xFF; break; case 0x90: /* switch 2 */ - temp_v0_6 = func_800BF11C(temp_s1); - temp_a1_2 = temp_s0_2 & 0xF; - sp34 = temp_a1_2; - sp52 = temp_v0_6; - if (func_800BEA10(arg0, temp_a1_2, temp_a1_2) == 0) { - (arg0 + (sp34 * 4))->unk48->unk50 = temp_s4->unk14 + sp52; + temp_v0_8 = m64_read_s16(temp_s1); + temp_a1 = temp_s0 & 0xF; + sp34 = temp_a1; + sp52 = temp_v0_8; + if (seq_channel_set_layer(seqChannel, temp_a1) == 0) { + seqChannel->layers[sp34]->scriptState.pc = &temp_s4->seqData[(u16) sp52]; } goto loop_12; case 0xA0: /* switch 2 */ - func_800BEB54(arg0, temp_s0_2 & 0xF); + seq_channel_layer_free(seqChannel, temp_s0 & 0xF); goto loop_12; case 0xB0: /* switch 2 */ - if (phi_s3 != -1) { - temp_a1_3 = temp_s0_2 & 0xF; - sp34 = temp_a1_3; - if (func_800BEA10(arg0, temp_a1_3, temp_a1_3) != -1) { - temp_v1_12 = arg0->unk34 + (phi_s3 * 2); - (arg0 + (sp34 * 4))->unk48->unk50 = temp_s4->unk14 + ((temp_v1_12->unk1 + (temp_v1_12->unk0 << 8)) & 0xFFFF); + if (var_s3 != -1) { + temp_a1_2 = temp_s0 & 0xF; + sp34 = temp_a1_2; + if (seq_channel_set_layer(seqChannel, temp_a1_2) != -1) { + temp_v1_10 = seqChannel->dynTable + (var_s3 * 2); + seqChannel->layers[sp34]->scriptState.pc = &temp_s4->seqData[(temp_v1_10->unk1 + (temp_v1_10->unk0 << 8)) & 0xFFFF]; } } goto loop_12; case 0x10: /* switch 2 */ - func_800BEE88(temp_s4, temp_s0_2 & 0xF, temp_s4->unk14 + (func_800BF11C(temp_s1) & 0xFFFF)); + sequence_channel_enable(temp_s4, temp_s0 & 0xF, &temp_s4->seqData[m64_read_s16(temp_s1) & 0xFFFF]); goto loop_12; case 0x20: /* switch 2 */ - func_800BEBA4(temp_s4[temp_s0_2 & 0xF].unk30); + sequence_channel_disable(temp_s4->channels[temp_s0 & 0xF]); goto loop_12; case 0x30: /* switch 2 */ sp55 = temp_t0; - (temp_s4[temp_t0].unk30 + func_800BF108(temp_s1))->unk58 = phi_s3; + temp_s4->channels[temp_t0]->soundScriptIO[m64_read_u8(temp_s1)] = var_s3; goto loop_12; case 0x40: /* switch 2 */ sp55 = temp_t0; - phi_s3 = (temp_s4[temp_t0].unk30 + func_800BF108(temp_s1))->unk58; + var_s3 = temp_s4->channels[temp_t0]->soundScriptIO[m64_read_u8(temp_s1)]; goto loop_12; } + break; } } - phi_s1_2 = arg0; + var_s1_2 = seqChannel; + var_s0_2 = 0; do { - temp_a0_5 = phi_s1_2->unk48; - if (temp_a0_5 != 0) { - func_800BF190(temp_a0_5); + temp_a0_5 = var_s1_2->layers[0]; + if (temp_a0_5 != NULL) { + seq_channel_layer_process_script(temp_a0_5); } - temp_s0_7 = phi_s0_2 + 4; - phi_s1_2 += 4; - phi_s0_2 = temp_s0_7; - } while (temp_s0_7 != 0x10); + var_s0_2 += 4; + var_s1_2 += 4; + } while (var_s0_2 != 0x10); } - /* Duplicate return node #109. Try simplifying control flow for better match */ } } #else @@ -1525,19 +1194,19 @@ GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800BFD90.s") #ifdef MIPS_TO_C //generated by mips_to_c commit bd0364fa19633bd6201f8007e2d0a7ed87825909 -void func_800BAB58(void *, void *, void *, void *, void *); /* extern */ +void audio_dma_partial_copy_async(void *, void *, void *, void *, void *); /* extern */ void func_800BB584(u8, void *, void *); /* extern */ -void func_800BD418(void *); /* extern */ -void func_800BD578(void *, s8); /* extern */ -void func_800BEC8C(void *, s32); /* extern */ -void func_800BEDB8(void *, s32); /* extern */ -void func_800BEE88(void *, s32, s32); /* extern */ -void func_800BEF2C(void *, u8, s32); /* extern */ +void note_pool_clear(void *); /* extern */ +void note_pool_fill(void *, s8); /* extern */ +void sequence_player_init_channels(void *, s32); /* extern */ +void sequence_player_disable_channels(void *, s32); /* extern */ +void sequence_channel_enable(void *, s32, s32); /* extern */ +void sequence_player_disable(void *, u8, s32); /* extern */ void func_800BFD90(s32); /* extern */ s32 osRecvMesg(void *, ?, ?); /* extern */ -extern u8 D_803B03C0; -extern ? D_803B0400; -extern ? D_803B5EF0; +extern u8 gBankLoadStatus; +extern ? gSeqLoadStatus; +extern ? gSequenceChannelNone; void func_800C08CC(void *arg0) { void *sp38; @@ -1598,7 +1267,7 @@ void func_800C08CC(void *arg0) { if (arg0->unk144 == 0) { arg0->unk0 = arg0->unk0 & 0xFFF7; func_800BB584(arg0->unk6, temp_a1, temp_a2); - temp_v0_2 = arg0->unk6 + &D_803B03C0; + temp_v0_2 = arg0->unk6 + &gBankLoadStatus; if (*temp_v0_2 != 5) { *temp_v0_2 = 2; return; @@ -1606,7 +1275,7 @@ void func_800C08CC(void *arg0) { /* Duplicate return node #110. Try simplifying control flow for better match */ return; } - func_800BAB58(arg0 + 0x140, temp_a1, temp_a2, temp_s0, arg0 + 0x124); + audio_dma_partial_copy_async(arg0 + 0x140, temp_a1, temp_a2, temp_s0, arg0 + 0x124); return; } /* Duplicate return node #110. Try simplifying control flow for better match */ @@ -1615,7 +1284,7 @@ void func_800C08CC(void *arg0) { if (((temp_v0 * 8) >> 0x1F) == 1) { if (osRecvMesg(arg0 + 0xD4, 0, 0) != -1) { arg0->unk0 = arg0->unk0 & 0xFFEF; - temp_v1 = arg0->unk4 + &D_803B0400; + temp_v1 = arg0->unk4 + &gSeqLoadStatus; if (*temp_v1 != 5) { *temp_v1 = 2; } @@ -1625,15 +1294,15 @@ void func_800C08CC(void *arg0) { return; } block_11: - temp_v1_2 = arg0->unk4 + &D_803B0400; + temp_v1_2 = arg0->unk4 + &gSeqLoadStatus; temp_a1_2 = *temp_v1_2; - if ((temp_a1_2 < 2) || (temp_v0_3 = arg0->unk5 + &D_803B03C0, temp_a0 = *temp_v0_3, phi_a0 = temp_a0, phi_v0 = temp_v0_3, ((temp_a0 < 2) != 0))) { - func_800BEF2C(arg0, temp_a1_2, 5); + if ((temp_a1_2 < 2) || (temp_v0_3 = arg0->unk5 + &gBankLoadStatus, temp_a0 = *temp_v0_3, phi_a0 = temp_a0, phi_v0 = temp_v0_3, ((temp_a0 < 2) != 0))) { + sequence_player_disable(arg0, temp_a1_2, 5); return; } if (temp_a1_2 != 5) { *temp_v1_2 = 2; - temp_v0_4 = arg0->unk5 + &D_803B03C0; + temp_v0_4 = arg0->unk5 + &gBankLoadStatus; phi_a0 = *temp_v0_4; phi_v0 = temp_v0_4; } @@ -1655,12 +1324,12 @@ block_11: arg0->unk0 = arg0->unk0 | 4; phi_s3 = sp58; loop_24: - temp_v0_6 = func_800BF108(temp_s0_2); + temp_v0_6 = m64_read_u8(temp_s0_2); temp_s2 = temp_v0_6 & 0xFF; if (temp_v0_6 == 0xFF) { temp_a0_3 = temp_s0_2->unk18; if (temp_a0_3 == 0) { - func_800BEF2C(arg0); + sequence_player_disable(arg0); } else { temp_t9 = (temp_a0_3 - 1) & 0xFF; temp_s0_2->unk18 = temp_t9; @@ -1672,20 +1341,20 @@ block_28: temp_v1_4 = temp_v0_6 & 0xFF; temp_v0_7 = temp_v1_4 & 0xF0; if (temp_v1_4 == 0xFD) { - arg0->unkE = func_800BF14C(temp_s0_2); + arg0->unkE = m64_read_compressed_u16(temp_s0_2); } else if (temp_v1_4 == 0xFE) { arg0->unkE = 1; } else { if (temp_v1_4 >= 0xC0) { switch (temp_v1_4) { /* switch 1 */ case 0xFC: /* switch 1 */ - temp_t2_2 = func_800BF11C(temp_s0_2) & 0xFFFF; + temp_t2_2 = m64_read_s16(temp_s0_2) & 0xFFFF; (temp_s0_2 + (temp_s0_2->unk18 * 4))->unk4 = temp_s0_2->unk0; temp_s0_2->unk18 = temp_s0_2->unk18 + 1; temp_s0_2->unk0 = arg0->unk14 + temp_t2_2; break; case 0xF8: /* switch 1 */ - (temp_s0_2 + temp_s0_2->unk18)->unk14 = func_800BF108(temp_s0_2); + (temp_s0_2 + temp_s0_2->unk18)->unk14 = m64_read_u8(temp_s0_2); (temp_s0_2 + (temp_s0_2->unk18 * 4))->unk4 = temp_s0_2->unk0; temp_s0_2->unk18 = temp_s0_2->unk18 + 1; break; @@ -1704,34 +1373,34 @@ block_28: case 0xFA: /* switch 1 */ case 0xFB: /* switch 1 */ if (((temp_s2 != 0xFA) || (phi_s3 == 0)) && ((temp_s2 != 0xF9) || (phi_s3 < 0)) && ((temp_s2 != 0xF5) || (phi_s3 >= 0))) { - temp_s0_2->unk0 = arg0->unk14 + (func_800BF11C(temp_s0_2) & 0xFFFF); + temp_s0_2->unk0 = arg0->unk14 + (m64_read_s16(temp_s0_2) & 0xFFFF); } break; case 0xF2: /* switch 1 */ case 0xF3: /* switch 1 */ case 0xF4: /* switch 1 */ if (((temp_s2 != 0xF3) || (phi_s3 == 0)) && ((temp_s2 != 0xF2) || (phi_s3 < 0))) { - temp_s0_2->unk0 = temp_s0_2->unk0 + func_800BF108(temp_s0_2); + temp_s0_2->unk0 = temp_s0_2->unk0 + m64_read_u8(temp_s0_2); } break; case 0xF1: /* switch 1 */ temp_a0_5 = arg0 + 0x94; sp38 = temp_a0_5; - func_800BD418(temp_a0_5); - func_800BD578(temp_a0_5, func_800BF108(temp_s0_2)); + note_pool_clear(temp_a0_5); + note_pool_fill(temp_a0_5, m64_read_u8(temp_s0_2)); break; case 0xF0: /* switch 1 */ - func_800BD418(arg0 + 0x94); + note_pool_clear(arg0 + 0x94); break; case 0xDF: /* switch 1 */ arg0->unkC = 0; /* fallthrough */ case 0xDE: /* switch 1 */ - arg0->unkC = arg0->unkC + func_800BF108(temp_s0_2); + arg0->unkC = arg0->unkC + m64_read_u8(temp_s0_2); break; case 0xDC: /* switch 1 */ case 0xDD: /* switch 1 */ - temp_v0_9 = func_800BF108(temp_s0_2); + temp_v0_9 = m64_read_u8(temp_s0_2); if (temp_s2 == 0xDD) { arg0->unk8 = (temp_v0_9 & 0xFF) * 0x30; } else { @@ -1749,8 +1418,8 @@ block_28: } break; case 0xDA: /* switch 1 */ - temp_s2_2 = func_800BF108(temp_s0_2) & 0xFF; - temp_v0_11 = func_800BF11C(temp_s0_2); + temp_s2_2 = m64_read_u8(temp_s0_2) & 0xFF; + temp_v0_11 = m64_read_s16(temp_s0_2); if ((temp_s2_2 != 0) && (temp_s2_2 != 1)) { if (temp_s2_2 != 2) { @@ -1766,7 +1435,7 @@ block_28: } break; case 0xDB: /* switch 1 */ - temp_v0_12 = func_800BF108(temp_s0_2); + temp_v0_12 = m64_read_u8(temp_s0_2); temp_v1_6 = arg0->unk1; if (temp_v1_6 != 0) { if (temp_v1_6 != 1) { @@ -1790,26 +1459,26 @@ block_76: } break; case 0xD9: /* switch 1 */ - arg0->unk28 = func_800BF108(temp_s0_2) / 127.0f; + arg0->unk28 = m64_read_u8(temp_s0_2) / 127.0f; break; case 0xD7: /* switch 1 */ - func_800BEC8C(arg0, func_800BF11C(temp_s0_2) & 0xFFFF); + sequence_player_init_channels(arg0, m64_read_s16(temp_s0_2) & 0xFFFF); break; case 0xD6: /* switch 1 */ - func_800BEDB8(arg0, func_800BF11C(temp_s0_2) & 0xFFFF); + sequence_player_disable_channels(arg0, m64_read_s16(temp_s0_2) & 0xFFFF); break; case 0xD5: /* switch 1 */ - arg0->unk24 = func_800BF108(temp_s0_2) / 127.0f; + arg0->unk24 = m64_read_u8(temp_s0_2) / 127.0f; break; case 0xD4: /* switch 1 */ arg0->unk0 = arg0->unk0 | 0x20; break; case 0xD3: /* switch 1 */ - arg0->unk3 = func_800BF108(temp_s0_2); + arg0->unk3 = m64_read_u8(temp_s0_2); break; case 0xD1: /* switch 1 */ case 0xD2: /* switch 1 */ - temp_v1_8 = arg0->unk14 + (func_800BF11C(temp_s0_2) & 0xFFFF); + temp_v1_8 = arg0->unk14 + (m64_read_s16(temp_s0_2) & 0xFFFF); if (temp_s2 == 0xD2) { arg0->unk8C = temp_v1_8; } else { @@ -1817,16 +1486,16 @@ block_76: } break; case 0xD0: /* switch 1 */ - arg0->unk2 = func_800BF108(temp_s0_2); + arg0->unk2 = m64_read_u8(temp_s0_2); break; case 0xCC: /* switch 1 */ - phi_s3 = func_800BF108(temp_s0_2); + phi_s3 = m64_read_u8(temp_s0_2); break; case 0xC9: /* switch 1 */ - phi_s3 &= func_800BF108(temp_s0_2); + phi_s3 &= m64_read_u8(temp_s0_2); break; case 0xC8: /* switch 1 */ - phi_s3 -= func_800BF108(temp_s0_2); + phi_s3 -= m64_read_u8(temp_s0_2); break; } } else if (temp_v0_7 >= 0x11) { @@ -1842,7 +1511,7 @@ block_76: phi_s3 = arg0->unk7; break; case 0x90: /* switch 2 */ - func_800BEE88(arg0, temp_s2 & 0xF, arg0->unk14 + (func_800BF11C(temp_s0_2) & 0xFFFF)); + sequence_channel_enable(arg0, temp_s2 & 0xF, arg0->unk14 + (m64_read_s16(temp_s0_2) & 0xFFFF)); break; } } else if (temp_v0_7 != 0x20) { @@ -1863,7 +1532,7 @@ block_76: phi_v0_3 = 0; do { temp_a0_6 = phi_v1->unk30; - if ((&D_803B5EF0 != temp_a0_6) == 1) { + if ((&gSequenceChannelNone != temp_a0_6) == 1) { sp34 = phi_v0_3; sp30 = phi_v1; func_800BFD90(temp_a0_6); @@ -1883,169 +1552,90 @@ GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800C08CC.s") #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BCBC4(); // extern -void func_800BDFF8(u32 *); // extern +void process_notes(); // extern +void sequence_player_process_sound(u32 *); // extern void func_800C08CC(u32 *); // extern -extern u32 D_803B1510; -extern ? D_803B1A30; +extern u32 gSequencePlayers; +extern ? gSequenceChannels; void func_800C1138(s32 arg0) { u32 *temp_s0; u32 *phi_s0; - phi_s0 = &D_803B1510; + phi_s0 = &gSequencePlayers; do { if ((*phi_s0 >> 0x1F) == 1) { func_800C08CC(phi_s0); - func_800BDFF8(phi_s0); + sequence_player_process_sound(phi_s0); } temp_s0 = phi_s0 + 0x148; phi_s0 = temp_s0; - } while (temp_s0 != &D_803B1A30); - func_800BCBC4(); + } while (temp_s0 != &gSequenceChannels); + process_notes(); } #else GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800C1138.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BEF2C(void *); // extern -extern u32 D_803B1510; -extern u8 gDefaultShortNoteDurationTable; -extern u8 gDefaultShortNoteVelocityTable; - -void func_800C11B0(s32 arg0) { - void *sp18; - void *temp_a0; - - temp_a0 = (arg0 * 0x148) + &D_803B1510; - sp18 = temp_a0; - func_800BEF2C(temp_a0); - temp_a0->unkE = 0; - temp_a0->unk1 = 1; - temp_a0->unk10 = 0; - temp_a0->unk12 = 0; - temp_a0->unkA = 0; - temp_a0->unk8 = 0x1680; - temp_a0->unkC = 0; - temp_a0->unk2 = 0; - temp_a0->unk8C = &gDefaultShortNoteVelocityTable; - temp_a0->unk90 = &gDefaultShortNoteDurationTable; - temp_a0->unk18 = 1.0f; - temp_a0->unk28 = 1.0f; - temp_a0->unk1C = 0.0f; - temp_a0->unk20 = 0.0f; - temp_a0->unk24 = 0.5f; +void init_sequence_player(u32 player) { + struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; + sequence_player_disable(seqPlayer); + seqPlayer->delay = 0; + seqPlayer->state = 1; + seqPlayer->fadeRemainingFrames = 0; + seqPlayer->fadeTimerUnkEu = 0; + seqPlayer->tempoAcc = 0; + seqPlayer->tempo = 120 * TEMPO_SCALE; // 120 BPM + seqPlayer->transposition = 0; + seqPlayer->noteAllocPolicy = 0; + seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable; + seqPlayer->shortNoteDurationTable = gDefaultShortNoteDurationTable; + seqPlayer->fadeVolume = 1.0f; + seqPlayer->fadeVolumeScale = 1.0f; + seqPlayer->fadeVelocity = 0.0f; + seqPlayer->volume = 0.0f; + seqPlayer->muteVolumeScale = 0.5f; } + +void init_sequence_players(void) { + // Initialization function, called from audio_init + s32 i, j; + + for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { + gSequenceChannels[i].seqPlayer = NULL; + gSequenceChannels[i].enabled = FALSE; + // @bug Size of wrong array. Zeroes out second half of gSequenceChannels[0], + // all of gSequenceChannels[1..31], and part of gSequenceLayers[0]. + // However, this is only called at startup, so it's harmless. +#ifdef AVOID_UB +#define LAYERS_SIZE LAYERS_MAX #else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800C11B0.s") +#define LAYERS_SIZE ARRAY_COUNT(gSequenceLayers) #endif + for (j = 0; j < LAYERS_SIZE; j++) { + gSequenceChannels[i].layers[j] = NULL; + } + } -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800BD318(? *); // extern -void func_800BF084(s32, ? *, u32, u8 *); // extern -void func_800C11B0(s32); // extern -extern u32 D_803B1510; -extern ? D_803B15A4; -extern ? D_803B1A30; -extern u8 D_803B3EF0; -extern ? D_803B5EF0; + init_layer_freelist(); -void func_800C125C(void) { - ? *temp_a1; - ? *temp_v1; - ? *temp_v1_2; - s32 temp_s3; - s32 temp_v0; - s32 temp_v0_3; - u32 temp_a2; - u8 *temp_v0_2; - u8 temp_t4; - u8 temp_t6; - u8 temp_t8; - ? *phi_a1; - ? *phi_v1; - s32 phi_v0; - ? *phi_a2; - u8 *phi_v0_2; - ? *phi_v1_2; - s32 phi_v0_3; - ? *phi_s1; - ? *phi_s5; - s32 phi_s3; - ? *phi_s4; + for (i = 0; i < ARRAY_COUNT(gSequenceLayers); i++) { + gSequenceLayers[i].seqChannel = NULL; + gSequenceLayers[i].enabled = FALSE; + } - phi_a1 = &D_803B1A30; - phi_a2 = &D_803B1A30; - do { - phi_a1->unk44 = 0; - phi_a1->unk0 = phi_a1->unk0 & 0xFF7F; - phi_v1 = phi_a2; - phi_v0 = 0; - phi_v0_3 = 0; -loop_2: - temp_v0 = phi_v0 + 4; - phi_v1->unk4C = 0; - phi_v1->unk50 = 0; - phi_v1->unk54 = 0; - temp_v1 = phi_v1 + 0x10; - temp_v1->unk38 = 0; - phi_v1 = temp_v1; - phi_v0 = temp_v0; - if (temp_v0 != 0x40) { - goto loop_2; + for (i = 0; i < SEQUENCE_PLAYERS; i++) { + for (j = 0; j < CHANNELS_MAX; j++) { + gSequencePlayers[i].channels[j] = &gSequenceChannelNone; } - temp_a2 = phi_a2 + 0xC4; - temp_a1 = phi_a1 + 0xC4; - phi_a1 = temp_a1; - phi_a2 = temp_a2; - } while (temp_a2 < &D_803B3EF0); - func_800BF084(0x40, temp_a1, temp_a2, &D_803B3EF0); - phi_v0_2 = &D_803B3EF0; - do { - temp_v0_2 = phi_v0_2 + 0x80; - temp_v0_2->unk-34 = 0; - temp_v0_2->unk-80 = *phi_v0_2 & 0xFF7F; - phi_v0_2 = temp_v0_2; - } while (temp_v0_2 < &D_803B5EF0); - phi_s1 = &D_803B1510; - phi_s5 = &D_803B15A4; - phi_s3 = 0; - phi_s4 = &D_803B1510; - do { - phi_v1_2 = phi_s4; -loop_8: - temp_v0_3 = phi_v0_3 + 4; - phi_v1_2->unk34 = &D_803B5EF0; - phi_v1_2->unk38 = &D_803B5EF0; - phi_v1_2->unk3C = &D_803B5EF0; - temp_v1_2 = phi_v1_2 + 0x10; - temp_v1_2->unk20 = &D_803B5EF0; - phi_v1_2 = temp_v1_2; - phi_v0_3 = temp_v0_3; - if (temp_v0_3 != 0x10) { - goto loop_8; - } - phi_s1->unk7 = -1; - phi_s1->unk3 = 0xE0; - temp_t4 = phi_s1->unk0 & 0xFF7F; - temp_t6 = temp_t4 & 0xDF; - phi_s1->unk0 = temp_t4; - temp_t8 = temp_t6 & 0xF7; - phi_s1->unk0 = temp_t6; - phi_s1->unk0 = temp_t8; - phi_s1->unk0 = temp_t8 & 0xEF; - func_800BD318(phi_s5); - func_800C11B0(phi_s3); - temp_s3 = phi_s3 + 1; - phi_s1 += 0x148; - phi_s5 += 0x148; - phi_s3 = temp_s3; - phi_s4 += 0x148; - } while (temp_s3 != 4); + + gSequencePlayers[i].seqVariationEu[0] = -1; + gSequencePlayers[i].muteBehavior = MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES | MUTE_BEHAVIOR_SOFTEN; + gSequencePlayers[i].enabled = FALSE; + gSequencePlayers[i].muted = FALSE; + gSequencePlayers[i].bankDmaInProgress = FALSE; + gSequencePlayers[i].seqDmaInProgress = FALSE; + init_note_lists(&gSequencePlayers[i].notePool); + init_sequence_player(i); + } } -#else -GLOBAL_ASM("asm/non_matchings/audio/seqplayer/func_800C125C.s") -#endif diff --git a/src/audio/seqplayer.h b/src/audio/seqplayer.h new file mode 100644 index 000000000..558278c7b --- /dev/null +++ b/src/audio/seqplayer.h @@ -0,0 +1,41 @@ +#ifndef AUDIO_SEQPLAYER_H +#define AUDIO_SEQPLAYER_H + +#include <PR/ultratypes.h> + +#include "audio/internal.h" + +#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80) +#define PORTAMENTO_MODE(x) ((x).mode & ~0x80) +#define PORTAMENTO_MODE_1 1 +#define PORTAMENTO_MODE_2 2 +#define PORTAMENTO_MODE_3 3 +#define PORTAMENTO_MODE_4 4 +#define PORTAMENTO_MODE_5 5 + +void sequence_channel_init(struct SequenceChannel *seqChannel); +s32 seq_channel_set_layer(struct SequenceChannel *seqChannel, s32 layerIndex); +void seq_channel_layer_disable(struct SequenceChannelLayer *seqPlayer); +void seq_channel_layer_free(struct SequenceChannel *seqChannel, s32 layerIndex); +void sequence_channel_disable(struct SequenceChannel *seqPlayer); +struct SequenceChannel *allocate_sequence_channel(void); +void sequence_player_init_channels(struct SequencePlayer *seqPlayer, u16 channelBits); +void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 channelBits); +void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *script); +void sequence_player_disable(struct SequencePlayer* seqPlayer); +void func_800BEF2C(struct SequencePlayer* seqPlayer); +void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item); +void *audio_list_pop_back(struct AudioListItem *list); +void init_layer_freelist(void); +u8 m64_read_u8(struct M64ScriptState *state); +s16 m64_read_s16(struct M64ScriptState *state); +u16 m64_read_compressed_u16(struct M64ScriptState *state); +void seq_channel_layer_process_script(struct SequenceChannelLayer *layer); +u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, struct AdsrSettings *adsr); +void set_instrument(struct SequenceChannel *seqChannel, u8 instId); +void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume); +// void process_sequences(s32 iterationsRemaining); +void init_sequence_player(u32 player); +void init_sequence_players(void); + +#endif // AUDIO_SEQPLAYER_H diff --git a/src/audio/synthesis.c b/src/audio/synthesis.c index 1fd448b9f..5a8f7da4e 100644 --- a/src/audio/synthesis.c +++ b/src/audio/synthesis.c @@ -1,12 +1,12 @@ #include <ultra64.h> #include <macros.h> -#include "synthesis.h" -//#include "heap.h" -//#include "data.h" -//#include "load.h" -//#include "seqplayer.h" -#include "internal.h" -//#include "external.h" +#include "audio/synthesis.h" +//#include "audio/heap.h" +//#include "audio/data.h" +#include "audio/load.h" +//#include "audio/seqplayer.h" +#include "audio/internal.h" +//#include "audio/external.h" #include "PR/abi.h" #define aSetLoadBufferPair(pkt, c, off) \ @@ -30,10 +30,7 @@ struct VolumeChange { u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex); u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s16 *aiBuf, s32 bufLen, u64 *cmd); -u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad); -u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags); u64 *process_envelope(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamples, u16 inBuf, s32 headsetPanSettings, u32 flags); -u64 *note_apply_headset_pan_effects(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight); u64 gGfxSPTaskOutputBuffer[0x3F00]; @@ -122,96 +119,54 @@ Acmd *synthesis_save_reverb_ring_buffer(Acmd *acmd, u16 addr, u16 destOffset, s3 return acmd; } -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -Tried to use struct NoteSubEu before it is defined. -extern ? gAudioBufferParameters; -extern s32 gMaxSimultaneousNotes; -extern ? gNoteSubsEu; - -void synthesis_load_note_subs_eu(s32 arg0, s32 arg1) { - s32 *temp_a0; - s32 temp_v0; - s32 temp_v0_2; - s32 phi_v0; +void func_800B6FB4(s32 updateIndexStart, s32 noteIndex) { + s32 i; - temp_v0 = arg0 + 1; - phi_v0 = temp_v0; - if (temp_v0 < gAudioBufferParameters.unkC) { - // Error: Tried to use struct NoteSubEu before it is defined. - // At instruction: lui $a1, %hi(gNoteSubsEu) -loop_2: - temp_a0 = *arg1 + (gMaxSimultaneousNotes * phi_v0 * 0x10) + (arg1 * 0x10); - if ((*temp_a0 * 2) >= 0) { - temp_v0_2 = phi_v0 + 1; - *temp_a0 = *temp_a0 & 0xFF7F; - phi_v0 = temp_v0_2; - if (temp_v0_2 < gAudioBufferParameters.unkC) { - goto loop_2; - } + for (i = updateIndexStart + 1; i < gAudioBufferParameters.updatesPerFrame; i++) { + if (!gNoteSubsEu[gMaxSimultaneousNotes * i + noteIndex].needsInit) { + gNoteSubsEu[gMaxSimultaneousNotes * i + noteIndex].enabled = FALSE; + } else { + break; } } } -#else -GLOBAL_ASM("asm/non_matchings/audio/synthesis/synthesis_load_note_subs_eu.s") -#endif - -#ifdef MIPS_TO_C -//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c -extern s32 D_803B1508; -void func_800B7034(s32 arg0) { - s32 var_a1; - s32 var_v0; - struct NoteSub *temp_a2; - void *temp_a0; - void *temp_a0_2; - - var_v0 = 0; - var_a1 = 0; - if (gMaxSimultaneousNotes > 0) { - do { - temp_a0 = var_a1 + D_803B1508; - temp_a0_2 = temp_a0 + 0xB0; - temp_a2 = &gNoteSubsEu[(gMaxSimultaneousNotes * arg0) + var_v0]; - if (((u32) temp_a0->unkB0 >> 0x1F) != 0) { - temp_a2->unk0 = (s32) temp_a0_2->unk0; - temp_a2->unk4 = (s32) temp_a0_2->unk4; - temp_a2->unk8 = (s32) temp_a0_2->unk8; - temp_a2->sound.samples = temp_a0_2->unkC; - temp_a0_2->unk0 = (s8) ((u8) temp_a0_2->unk0 & 0xFFBF); - } else { - temp_a2->unk0 = (s8) ((u8) temp_a2->unk0 & 0xFF7F); - } - var_v0 += 1; - var_a1 += 0xC0; - } while (var_v0 < gMaxSimultaneousNotes); +void synthesis_load_note_subs_eu(s32 updateIndex) { + struct NoteSubEu *src; + struct NoteSubEu *dest; + s32 i; + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + src = &gNotes[i].noteSubEu; + dest = &gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + i]; + if (src->enabled) { + *dest = *src; + src->needsInit = FALSE; + } else { + dest->enabled = FALSE; + } } } -#else -GLOBAL_ASM("asm/non_matchings/audio/synthesis/func_800B7034.s") -#endif #ifdef MIPS_TO_C //generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c -? func_800B7034(s32); /* extern */ -Acmd *func_800B775C(s32, s16, Acmd *, s32); /* extern */ +Acmd *func_800B775C(s16 *, s16, Acmd *, s32); /* extern */ ? func_800C1138(s16); /* extern */ ? prepare_reverb_ring_buffer(s16, s32, s32); /* extern */ -Acmd *func_800B70EC(Acmd *acmd, s32 *arg1, s32 arg2, s16 arg3) { +Acmd *func_800B70EC(Acmd *acmd, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { Acmd *temp_v0; Acmd *var_fp; + s16 *var_s7; s16 temp_s0; s16 temp_v1; s16 temp_v1_2; - s16 var_s3; s16 var_s4; s16 var_s4_2; - s16 var_s6; s32 temp_lo; s32 var_s1; - s32 var_s7; + s32 var_s3; + s32 var_s6; s8 temp_v0_2; struct SynthesisReverb *var_s0; struct SynthesisReverb *var_s0_2; @@ -219,16 +174,16 @@ Acmd *func_800B70EC(Acmd *acmd, s32 *arg1, s32 arg2, s16 arg3) { u8 temp_v0_3; var_s4 = gAudioBufferParameters.updatesPerFrame; - var_s6 = arg3; + var_s6 = bufLen; if (var_s4 > 0) { do { temp_s0 = var_s4 - 1; func_800C1138(temp_s0); - func_800B7034(gAudioBufferParameters.updatesPerFrame - var_s4); + synthesis_load_note_subs_eu(gAudioBufferParameters.updatesPerFrame - var_s4); var_s4 = temp_s0; } while (temp_s0 > 0); } - var_s7 = arg2; + var_s7 = aiBuf; acmd->words.w0 = 0x07000000; acmd->words.w1 = 0; var_s4_2 = gAudioBufferParameters.updatesPerFrame; @@ -242,13 +197,13 @@ Acmd *func_800B70EC(Acmd *acmd, s32 *arg1, s32 arg2, s16 arg3) { temp_lo = var_s6 / var_s4_2; temp_v1 = gAudioBufferParameters.samplesPerUpdateMax; if (temp_lo >= temp_v1) { - var_s3 = temp_v1; + var_s3 = (s32) temp_v1; } else { temp_v1_2 = gAudioBufferParameters.samplesPerUpdateMin; if (temp_v1_2 >= temp_lo) { - var_s3 = temp_v1_2; + var_s3 = (s32) temp_v1_2; } else { - var_s3 = gAudioBufferParameters.samplesPerUpdate; + var_s3 = (s32) gAudioBufferParameters.samplesPerUpdate; } } } @@ -256,13 +211,13 @@ Acmd *func_800B70EC(Acmd *acmd, s32 *arg1, s32 arg2, s16 arg3) { var_s0 = gSynthesisReverbs; do { if (var_s0->useReverb != 0) { - prepare_reverb_ring_buffer(var_s3, gAudioBufferParameters.updatesPerFrame - var_s4_2, var_s1); + prepare_reverb_ring_buffer((s16) var_s3, gAudioBufferParameters.updatesPerFrame - var_s4_2, var_s1); } var_s1 += 1; var_s0 += 0x108; } while (var_s1 < gNumSynthesisReverbs); } - temp_v0 = func_800B775C(var_s7, var_s3, var_fp, gAudioBufferParameters.updatesPerFrame - var_s4_2); + temp_v0 = func_800B775C(var_s7, (s16) var_s3, var_fp, gAudioBufferParameters.updatesPerFrame - var_s4_2); var_s4_2 -= 1; var_fp = temp_v0; var_s6 -= var_s3; @@ -282,14 +237,14 @@ Acmd *func_800B70EC(Acmd *acmd, s32 *arg1, s32 arg2, s16 arg3) { var_s0_2->unk-105 = (s8) (temp_t4 ^ 1); } while ((u32) var_s0_2 < (u32) &gSynthesisReverbs[temp_v0_2]); } - *arg1 = (s32) (var_fp - acmd) >> 3; + *writtenCmds = (s32) (var_fp - acmd) >> 3; return var_fp; } #else GLOBAL_ASM("asm/non_matchings/audio/synthesis/func_800B70EC.s") #endif -Acmd *func_800B7304(Acmd *acmd, s32 bufLen, s16 reverbIndex, s16 updateIndex) { +Acmd *synthesis_resample_and_mix_reverb(Acmd *acmd, s32 bufLen, s16 reverbIndex, s16 updateIndex) { struct ReverbRingBufferItem *item; s16 startPad; s16 paddedLengthA; @@ -324,7 +279,7 @@ Acmd *func_800B7304(Acmd *acmd, s32 bufLen, s16 reverbIndex, s16 updateIndex) { return acmd; } -Acmd *func_800B7630(Acmd *acmd, s16 reverbIndex, s16 updateIndex) { +Acmd *synthesis_load_reverb_samples(Acmd *acmd, s16 reverbIndex, s16 updateIndex) { struct ReverbRingBufferItem *item; item = &gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex]; @@ -346,253 +301,165 @@ Acmd *func_800B7630(Acmd *acmd, s16 reverbIndex, s16 updateIndex) { } #ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -Tried to use struct NoteSubEu before it is defined. -Tried to use struct NoteSubEu before it is defined. -Tried to use struct NoteSubEu before it is defined. -Tried to use struct NoteSubEu before it is defined. -Tried to use struct NoteSubEu before it is defined. -void *func_800B7304(void *, s32, s16, s16); // extern -void *func_800B7630(void *, s16, s16); // extern -void *func_800B7C30(u8, s32, s32, s32, s32, void *, s32); // extern -extern u8 D_803B03C0; -extern s32 D_803B1508; -extern s32 gMaxSimultaneousNotes; -extern s32 D_803B7198; -extern ? gNoteSubsEu; -extern u8 gUseReverb; +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +Acmd *func_800B7C30(u8, struct NoteSub *, struct NoteSynthesisState *, s16 *, s32, Acmd *, s32); /* extern */ -void *func_800B775C(s32 arg0, s32 arg1, void *arg2, s16 arg3) { +Acmd *func_800B775C(s16 *aiBuf, s32 bufLen, Acmd *acmd, s32 updateIndex) { ? sp84; struct SynthesisReverb *sp64; - s16 temp_s3; - s16 temp_s3_2; + Acmd *temp_s4; + Acmd *temp_s4_2; + Acmd *var_s4; + s16 var_s2; + s16 var_s3; s32 temp_a0; s32 temp_a0_2; s32 temp_a0_3; s32 temp_lo; s32 temp_lo_2; - s32 temp_s1; - s32 temp_s1_2; - s32 temp_s1_3; - s32 temp_s1_4; - s32 temp_s1_5; - s32 temp_t0; - s32 temp_t0_2; s32 temp_t3_2; + s32 var_v1; + s32 var_v1_2; + s8 *temp_t4; + s8 *temp_t5; + s8 *temp_t8; s8 temp_t1; + s8 var_s1; + s8 var_s1_2; + struct NoteSub *temp_t0; + struct NoteSub *temp_t0_2; + struct NoteSub *temp_v0; + struct NoteSub *temp_v0_2; + struct NoteSub *var_v0; struct SynthesisReverb *temp_t9; + u8 *var_s0; + u8 *var_s0_2; u8 temp_a1; u8 temp_t3; u8 temp_v1; u8 temp_v1_2; - void *temp_s4; - void *temp_s4_2; - void *temp_s4_3; - void *temp_v0; - void *temp_v0_2; - void *temp_v0_3; - s8 phi_s1; - s16 phi_s2; - s16 phi_s3; - s8 phi_s1_2; - s16 phi_s2_2; - s8 phi_s1_3; - s32 phi_s2_3; - s16 phi_s3_2; - void *phi_s4; - s32 phi_s1_4; - s32 phi_s2_4; - u8 *phi_s0; - void *phi_s4_2; - s32 phi_s1_5; - void *phi_s4_3; - u8 *phi_s0_2; - void *phi_s4_4; - s32 phi_s1_6; - void *phi_s4_5; - s16 phi_s2_5; - s16 phi_s2_6; - s16 phi_s2_7; - s32 phi_s2_8; - s32 phi_s2_9; - void *phi_s4_6; - s32 phi_s1_7; - s32 phi_s1_8; - void *phi_s4_7; - s32 phi_s1_9; - void *phi_s4_8; - void *phi_s4_9; - s16 phi_s2_10; temp_t1 = gNumSynthesisReverbs; - phi_s2 = 0; - phi_s2_6 = 0; - phi_s2_8 = 0; - phi_s2_4 = 0; + var_s2 = 0; if (temp_t1 == 0) { temp_a0 = gMaxSimultaneousNotes; - phi_s1 = 0; + var_s1 = 0; if (temp_a0 > 0) { - // Error: Tried to use struct NoteSubEu before it is defined. - // At instruction: lui $t6, %hi(gNoteSubsEu) + var_v0 = &gNoteSubsEu[temp_a0 * updateIndex]; do { - phi_s2_5 = phi_s2; - if ((*MIPS2C_ERROR(Read from unset register $v0) >> 0x1F) != 0) { - *(arg1 + phi_s2) = phi_s1; - phi_s2_5 = phi_s2 + 1; + temp_t4 = &sp84 + var_s2; + if (((u32) *var_v0 >> 0x1F) != 0) { + var_s2 += 1; + *temp_t4 = var_s1; } - temp_s1 = phi_s1 + 1; - phi_s1 = temp_s1; - phi_s2 = phi_s2_5; - phi_s2_4 = phi_s2_5; - } while (temp_s1 < temp_a0); + var_s1 += 1; + var_v0 += 0x10; + } while (var_s1 < temp_a0); + var_s1 = 0; } - phi_s3_2 = 0; - phi_s1_7 = 0; + var_s3 = 0; } else { - phi_s3 = 0; + var_s3 = 0; if (temp_t1 > 0) { temp_a0_2 = gMaxSimultaneousNotes; do { - phi_s1_2 = 0; - phi_s2_2 = phi_s2_6; - phi_s2_10 = phi_s2_6; + var_s1_2 = 0; if (temp_a0_2 > 0) { - // Error: Tried to use struct NoteSubEu before it is defined. - // At instruction: lui $t0, %hi(gNoteSubsEu) + var_v1 = temp_a0_2 * updateIndex; do { - temp_v0 = (MIPS2C_ERROR(Read from unset register $v1) * 0x10) + MIPS2C_ERROR(Read from unset register $t0); - phi_s2_7 = phi_s2_2; - if (((temp_v0->unk0 >> 0x1F) != 0) && (phi_s3 == (temp_v0->unk1 >> 5))) { - *(&sp84 + phi_s2_2) = phi_s1_2; - phi_s2_7 = phi_s2_2 + 1; + temp_v0 = &gNoteSubsEu[var_v1]; + if (((u32) temp_v0->unk0 >> 0x1F) != 0) { + temp_t5 = &sp84 + var_s2; + if (var_s3 == ((u8) temp_v0->unk1 >> 5)) { + var_s2 += 1; + *temp_t5 = var_s1_2; + } } - temp_s1_2 = phi_s1_2 + 1; - phi_s1_2 = temp_s1_2; - phi_s2_2 = phi_s2_7; - phi_s2_10 = phi_s2_7; - } while (temp_s1_2 < temp_a0_2); + var_s1_2 += 1; + var_v1 += 1; + } while (var_s1_2 < temp_a0_2); } - temp_s3 = phi_s3 + 1; - phi_s3 = temp_s3; - phi_s2_6 = phi_s2_10; - phi_s2_8 = phi_s2_10; - } while (temp_s3 < temp_t1); + var_s3 += 1; + } while (var_s3 < temp_t1); + var_s3 = 0; } temp_a0_3 = gMaxSimultaneousNotes; - phi_s1_3 = 0; - phi_s2_3 = phi_s2_8; - phi_s2_4 = phi_s2_8; - phi_s3_2 = 0; - phi_s1_7 = 0; + var_s1 = 0; if (temp_a0_3 > 0) { - // Error: Tried to use struct NoteSubEu before it is defined. - // At instruction: lui $t0, %hi(gNoteSubsEu) + var_v1_2 = temp_a0_3 * updateIndex; do { - temp_v0_2 = (MIPS2C_ERROR(Read from unset register $v1) * 0x10) + MIPS2C_ERROR(Read from unset register $t0); - phi_s2_9 = phi_s2_3; - if (((temp_v0_2->unk0 >> 0x1F) != 0) && ((temp_v0_2->unk1 >> 5) >= temp_t1)) { - *(&sp84 + phi_s2_3) = phi_s1_3; - phi_s2_9 = phi_s2_3 + 1; + temp_v0_2 = &gNoteSubsEu[var_v1_2]; + if (((u32) temp_v0_2->unk0 >> 0x1F) != 0) { + temp_t8 = &sp84 + var_s2; + if ((s32) ((u8) temp_v0_2->unk1 >> 5) >= temp_t1) { + var_s2 += 1; + *temp_t8 = var_s1; + } } - temp_s1_3 = phi_s1_3 + 1; - phi_s1_3 = temp_s1_3; - phi_s2_3 = phi_s2_9; - phi_s2_4 = phi_s2_9; - } while (temp_s1_3 < temp_a0_3); + var_s1 += 1; + var_v1_2 += 1; + } while (var_s1 < temp_a0_3); + var_s1 = 0; } } - arg2->unk4 = 0x300; - arg2->unk0 = 0x2000540; - temp_s4_2 = arg2 + 8; - phi_s4 = temp_s4_2; - phi_s1_4 = phi_s1_7; - phi_s1_9 = phi_s1_7; - phi_s4_8 = temp_s4_2; + acmd->words.w1 = 0x00000300; + acmd->words.w0 = 0x02000540; + var_s4 = acmd + 8; if (gNumSynthesisReverbs > 0) { - // Error: Tried to use struct NoteSubEu before it is defined. - // At instruction: lui $s6, %hi(gNoteSubsEu) do { - temp_t9 = &gSynthesisReverbs[phi_s3_2]; + temp_t9 = &gSynthesisReverbs[var_s3]; sp64 = temp_t9; temp_t3 = temp_t9->useReverb; - gUseReverb = temp_t3; - phi_s1_5 = phi_s1_4; - phi_s1_8 = phi_s1_4; - phi_s4_7 = phi_s4; - if (temp_t3 != 0) { - phi_s4_7 = func_800B7304(phi_s4, arg1, phi_s3_2, arg3); + gUseReverb = (s8) temp_t3; + if ((s8) temp_t3 != 0) { + var_s4 = synthesis_resample_and_mix_reverb(var_s4, bufLen, var_s3, (s16) updateIndex); } - phi_s4_2 = phi_s4_7; - phi_s4_3 = phi_s4_7; - if (phi_s1_4 < phi_s2_4) { - phi_s0 = phi_s1_4 + &sp84; + if (var_s1 < var_s2) { + var_s0 = var_s1 + &sp84; loop_31: - temp_v1 = *phi_s0; - temp_t0 = *saved_reg_s6; - temp_lo = arg3 * gMaxSimultaneousNotes; - phi_s4_3 = phi_s4_2; - phi_s1_8 = phi_s1_5; - if (phi_s3_2 == ((temp_t0 + (temp_v1 * 0x10) + (temp_lo * 0x10))->unk1 >> 5)) { - temp_v0_3 = func_800B7C30(temp_v1, ((temp_v1 + temp_lo) * 0x10) + temp_t0, (temp_v1 * saved_reg_s7) + D_803B1508 + 0x10, arg0, arg1, phi_s4_2, arg3); - temp_s1_4 = phi_s1_5 + 1; - phi_s0 += 1; - phi_s4_2 = temp_v0_3; - phi_s1_5 = temp_s1_4; - phi_s4_3 = temp_v0_3; - phi_s1_8 = temp_s1_4; - if (temp_s1_4 < phi_s2_4) { + temp_v1 = *var_s0; + temp_t0 = gNoteSubsEu; + temp_lo = updateIndex * gMaxSimultaneousNotes; + if (var_s3 == ((u8) (&temp_t0[temp_v1])[temp_lo].unk1 >> 5)) { + var_s1 += 1; + var_s4 = func_800B7C30(temp_v1, &temp_t0[temp_v1 + temp_lo], &gNotes[temp_v1].synthesisState, aiBuf, bufLen, var_s4, updateIndex); + var_s0 += 1; + if (var_s1 < var_s2) { goto loop_31; } } } - phi_s1_4 = phi_s1_8; - phi_s4_6 = phi_s4_3; - phi_s1_9 = phi_s1_8; if (sp64->useReverb != 0) { - phi_s4_6 = func_800B7630(phi_s4_3, phi_s3_2, arg3); + var_s4 = synthesis_load_reverb_samples(var_s4, var_s3, (s16) updateIndex); } - temp_s3_2 = phi_s3_2 + 1; - phi_s3_2 = temp_s3_2; - phi_s4 = phi_s4_6; - phi_s4_8 = phi_s4_6; - } while (temp_s3_2 < gNumSynthesisReverbs); + var_s3 += 1; + } while (var_s3 < gNumSynthesisReverbs); } - // Error: Tried to use struct NoteSubEu before it is defined. - // At instruction: lui $s6, %hi(gNoteSubsEu) - phi_s4_4 = phi_s4_8; - phi_s1_6 = phi_s1_9; - phi_s4_5 = phi_s4_8; - if (MIPS2C_ERROR()) { - phi_s0_2 = phi_s1_9 + &sp84; + if (var_s1 < var_s2) { + var_s0_2 = var_s1 + &sp84; do { - temp_v1_2 = *phi_s0_2; - temp_t0_2 = *saved_reg_s6; - temp_lo_2 = arg3 * gMaxSimultaneousNotes; - temp_a1 = (temp_t0_2 + (temp_v1_2 * 0x10) + (temp_lo_2 * 0x10))->unk2; - phi_s4_9 = phi_s4_4; - if (((*(&D_803B03C0 + temp_a1) < 2) ^ 1) == 1) { - phi_s4_9 = func_800B7C30(temp_v1_2, ((temp_v1_2 + temp_lo_2) * 0x10) + temp_t0_2, (temp_v1_2 * saved_reg_s7) + D_803B1508 + 0x10, arg0, arg1, phi_s4_4, arg3); + temp_v1_2 = *var_s0_2; + temp_t0_2 = gNoteSubsEu; + temp_lo_2 = updateIndex * gMaxSimultaneousNotes; + temp_a1 = (&temp_t0_2[temp_v1_2])[temp_lo_2].bankId; + if ((((s32) gBankLoadStatus[temp_a1] < 2) ^ 1) == 1) { + var_s4 = func_800B7C30(temp_v1_2, &temp_t0_2[temp_v1_2 + temp_lo_2], &gNotes[temp_v1_2].synthesisState, aiBuf, bufLen, var_s4, updateIndex); } else { - D_803B7198 = temp_a1 + (phi_s1_6 << 8) + 0x10000000; + gAudioErrorFlags = temp_a1 + (var_s1 << 8) + 0x10000000; } - temp_s1_5 = phi_s1_6 + 1; - phi_s0_2 += 1; - phi_s4_4 = phi_s4_9; - phi_s1_6 = temp_s1_5; - phi_s4_5 = phi_s4_9; - } while (temp_s1_5 < phi_s2_4); + var_s1 += 1; + var_s0_2 += 1; + } while (var_s1 < var_s2); } - phi_s4_5->unk0 = 0x8000000; - temp_s4_3 = phi_s4_5 + 8; - temp_t3_2 = arg1 * 2; - phi_s4_5->unk4 = temp_t3_2 & 0xFFFF; - temp_s4 = temp_s4_3 + 8; - temp_s4_3->unk0 = 0xD000000; - temp_s4_3->unk4 = 0x54006C0; - temp_s4->unk0 = ((((temp_t3_2 * 2) >> 4) & 0xFF) << 0x10) | 0x15000000; - temp_s4->unk4 = arg0 + 0x80000000; + var_s4->words.w0 = 0x08000000; + temp_s4_2 = var_s4 + 8; + temp_t3_2 = bufLen * 2; + var_s4->words.w1 = temp_t3_2 & 0xFFFF; + temp_s4 = temp_s4_2 + 8; + temp_s4_2->words.w0 = 0x0D000000; + temp_s4_2->words.w1 = 0x054006C0; + temp_s4->words.w0 = ((((s32) (temp_t3_2 * 2) >> 4) & 0xFF) << 0x10) | 0x15000000; + temp_s4->words.w1 = (u32) (aiBuf + 0x80000000); return temp_s4 + 8; } #else @@ -600,17 +467,15 @@ GLOBAL_ASM("asm/non_matchings/audio/synthesis/func_800B775C.s") #endif #ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void *func_800B85B4(void *, void *, void *, u32); // extern -s32 func_800B8644(void *, void *, s32, u16, s32, s32); // extern -s32 func_800B86A0(s32, void *, void *, s32, s32, s32, s32); // extern -s32 func_800B8A2C(s32, void *, void *, s32, s32, s32); // extern -s32 func_800BAD0C(s32, s32, s32, void *); // extern -void synthesis_load_note_subs_eu(s32, s32, s32, s32); // extern -extern s32 D_803B1508; -extern s32 gUnknownData_800F6290; - -s32 func_800B7C30(s32 arg0, void *arg1, void *arg2, ? arg3, s32 arg4, void *arg5, s32 arg6) { +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +Acmd *load_wave_samples(Acmd *, struct NoteSubEu *, struct NoteSynthesisState *, u32); /* extern */ +s32 final_resample(Acmd *, struct NoteSynthesisState *, s32, u16, s32, s32); /* extern */ +Acmd *func_800B86A0(s32, struct NoteSubEu *, struct NoteSynthesisState *, s32, s32, s32, s32); /* extern */ +Acmd *note_apply_headset_pan_effects(Acmd *, struct NoteSubEu *, struct NoteSynthesisState *, s32, s32, s32); /* extern */ +s32 func_800BAD0C(s32, s32, s32, u8 *); /* extern */ +extern ? gUnknownData_800F6290; + +Acmd *func_800B7C30(s32 noteIndex, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s16 *aiBuf, s32 bufLen, Acmd *acmd, s32 updateIndex) { void *sp130; void *sp12C; ? *sp128; @@ -625,125 +490,93 @@ s32 func_800B7C30(s32 arg0, void *arg1, void *arg2, ? arg3, s32 arg4, void *arg5 s32 spD8; s32 spB0; s32 spAC; - s32 spA0; + s32 spA0; /* compiler-managed */ u16 sp9E; - void *sp8C; + struct Note *sp8C; u32 sp50; ? *temp_a2_2; - s16 temp_t1; + Acmd *temp_s2; + Acmd *temp_s2_2; + Acmd *temp_s2_3; + Acmd *temp_v0_2; + Acmd *temp_v0_3; + Acmd *temp_v0_4; + Acmd *temp_v0_5; + Acmd *temp_v0_6; + Acmd *temp_v0_8; + Acmd *var_s2; + Acmd *var_s2_2; + s16 var_t1; s32 temp_a0; s32 temp_a0_2; - s32 temp_a0_3; - s32 temp_a0_4; - s32 temp_a0_5; - s32 temp_a0_6; - s32 temp_a0_7; - s32 temp_a0_8; s32 temp_a1_2; s32 temp_a1_3; s32 temp_a2; s32 temp_a2_3; s32 temp_a2_4; - s32 temp_a2_5; - s32 temp_a2_6; - s32 temp_a3; - s32 temp_fp; - s32 temp_s1; - s32 temp_s1_2; - s32 temp_s3; - s32 temp_t2; s32 temp_t6; s32 temp_t8; s32 temp_t9_2; - s32 temp_v0_3; - s32 temp_v0_4; + s32 temp_v0_7; s32 temp_v1; + s32 var_a0; + s32 var_a0_2; + s32 var_a2; + s32 var_a3; + s32 var_fp; + s32 var_s0; + s32 var_s0_2; + s32 var_s1; + s32 var_s3; + s32 var_s4; + s32 var_s5; + s32 var_s6; + s32 var_t0; + s32 var_t2; + s32 var_t3; + s32 var_t4; + s32 var_v1; + s32 var_v1_3; u16 temp_t7; u16 temp_v0; u32 temp_s0; u32 temp_t7_3; + u32 var_t5; + u32 var_t6; + u32 var_v1_2; void *temp_a1; - void *temp_s2; - void *temp_s2_2; - void *temp_s2_3; - void *temp_s2_4; void *temp_t7_2; void *temp_t9; - void *temp_v0_2; - s32 phi_v1; - void *phi_s2; - s32 phi_a0; - u32 phi_t5; - u32 phi_t5_2; - s32 phi_fp; - s32 phi_s3; - s32 phi_t0; - s32 phi_t3; - s32 phi_t4; - s32 phi_a0_2; - void *phi_s2_2; - s32 phi_s0; - void *phi_s2_3; - s32 phi_s1; - void *phi_s2_4; - s16 phi_t1; - s32 phi_t2; - s32 phi_s4; - s32 phi_s5; - s32 phi_s6; - s32 phi_t3_2; - s32 phi_s4_2; - void *phi_s2_5; - u32 phi_t5_3; - s32 phi_a3; - s32 phi_a2; - s32 phi_t4_2; - s32 phi_ra; - s32 phi_t5_4; - void *phi_s2_6; - u32 phi_v1_2; - void *phi_s2_7; - s32 phi_a0_3; - s32 phi_v1_3; - s32 phi_s0_2; - s32 phi_s2_8; - s32 phi_s1_2; - void *phi_s2_9; - u32 phi_t6; - s32 phi_a0_4; sp128 = NULL; - sp8C = (arg0 * 0xC0) + D_803B1508; - phi_v1 = 0; - phi_v1_3 = 0; - if (((arg1->unk0 * 2) >> 0x1F) == 1) { - arg2->unk0 = 0; - arg2->unk8 = 0; - arg2->unk4 = 0; - arg2->unk10 = 0; - arg2->unk12 = 0; - arg2->unk2 = 0; - arg2->unk3 = 0; - phi_v1 = 1; + sp8C = &gNotes[noteIndex]; + var_v1 = 0; + if (((u32) (noteSubEu->unk0 * 2) >> 0x1F) == 1) { + var_v1 = 1; + synthesisState->restart = 0; + synthesisState->samplePosInt = 0; + synthesisState->samplePosFrac = 0; + synthesisState->curVolLeft = 0; + synthesisState->curVolRight = 0; + synthesisState->prevHeadsetPanRight = 0; + synthesisState->prevHeadsetPanLeft = 0; } - temp_t7 = arg1->unkA; + temp_t7 = noteSubEu->resamplingRateFixedPoint; sp112 = temp_t7; - spB0 = (arg1->unk0 & 1) + 1; - temp_v0 = (temp_t7 * arg4 * 2) + arg2->unk4; - arg2->unk4 = temp_v0; + spB0 = ((u16) noteSubEu->unk0 & 1) + 1; + temp_v0 = (temp_t7 * bufLen * 2) + synthesisState->samplePosFrac; + synthesisState->samplePosFrac = temp_v0; temp_s0 = temp_v0 >> 0x10; - temp_a0 = arg1->unk0; - phi_a0_3 = temp_a0; - phi_a0 = temp_a0; - if (temp_a0 & 0x20000) { - temp_v0_2 = func_800B85B4(arg5, arg1, arg2, temp_s0); - temp_a2 = arg2->unk8; + var_a0 = noteSubEu->unk0; + if (var_a0 & 0x20000) { + temp_v0_2 = load_wave_samples(acmd, noteSubEu, synthesisState, temp_s0); + temp_a2 = synthesisState->samplePosInt; sp9E = (temp_a2 * 2) + 0x1A0; - arg2->unk8 = temp_a2 + temp_s0; - arg5 = temp_v0_2; - phi_a0_3 = arg1->unk0; + synthesisState->samplePosInt = temp_a2 + temp_s0; + var_a0 = noteSubEu->unk0; + acmd = temp_v0_2; } else { - temp_t7_2 = *arg1->unkC; + temp_t7_2 = *noteSubEu->sound.samples; sp130 = temp_t7_2; temp_t9 = temp_t7_2->unk8; sp12C = temp_t9; @@ -753,328 +586,270 @@ s32 func_800B7C30(s32 arg0, void *arg1, void *arg2, ? arg3, s32 arg4, void *arg5 spEC = temp_t7_2->unk4; if (spB0 > 0) { sp50 = temp_v0 >> 0x10; - sp114 = phi_v1; - phi_s2 = arg5; + sp114 = var_v1; + var_s2_2 = acmd; loop_6: temp_a1 = sp130->unkC; + var_fp = 0; + var_s4 = 0; temp_a2_2 = temp_a1 + 8; - phi_fp = 0; - phi_s4 = 0; - phi_s2_9 = phi_s2; if (spB0 == 1) { - phi_t5 = sp50; + var_t5 = sp50; } else { - phi_t5 = sp50; - if ((sp50 & 1) != 0) { - phi_t5 = (sp50 & ~1) + (spAC * 2); + var_t5 = sp50; + if (sp50 & 1) { + var_t5 = (sp50 & ~1) + (spAC * 2); } } - phi_t5_2 = phi_t5; - phi_t5_4 = phi_t5; if (sp128 != temp_a2_2) { - phi_s2->unk0 = ((temp_a1->unk0 * 0x10 * temp_a1->unk4) & 0xFFFFFF) | 0xB000000; - phi_s2->unk4 = (((arg1->unk0 << 0xB) >> 0x1D) * 2) + temp_a2_2 + 0x80000000; + temp_v0_3 = var_s2_2; + var_s2_2 += 8; + temp_v0_3->words.w0 = ((temp_a1->unk0 * 0x10 * temp_a1->unk4) & 0xFFFFFF) | 0x0B000000; + temp_v0_3->words.w1 = (((u32) (noteSubEu->unk0 << 0xB) >> 0x1D) * 2) + temp_a2_2 + 0x80000000; + var_a0 = noteSubEu->unk0; sp128 = temp_a2_2; - phi_a0 = arg1->unk0; - phi_s2_9 = phi_s2 + 8; } - phi_s2_2 = phi_s2_9; - phi_s2_6 = phi_s2_9; - if (((phi_a0 << 0xB) >> 0x1D) != 0) { + if (((u32) (var_a0 << 0xB) >> 0x1D) != 0) { sp128 = &gUnknownData_800F6290; } - if (phi_t5 != 0) { + if (var_t5 != 0) { loop_15: - temp_a2_3 = arg2->unk8; - temp_a0_2 = phi_t5_2 - phi_fp; - temp_s3 = temp_a2_3 & 0xF; + temp_a2_3 = synthesisState->samplePosInt; + temp_a0 = var_t5 - var_fp; + var_s3 = temp_a2_3 & 0xF; + var_t3 = 0; + var_t4 = 0; temp_v1 = spDC - temp_a2_3; - phi_s3 = temp_s3; - phi_t3 = 0; - phi_t4 = 0; - phi_s2_3 = phi_s2_2; - phi_t5_3 = phi_t5_2; - phi_ra = temp_a0_2; - if ((temp_s3 == 0) && (arg2->unk0 == 0)) { - phi_s3 = 0x10; + if ((var_s3 == 0) && (synthesisState->restart == 0)) { + var_s3 = 0x10; } - temp_a1_2 = 0x10 - phi_s3; - phi_s5 = temp_a1_2; - phi_s5 = temp_a1_2; - if (temp_a0_2 < temp_v1) { - temp_t9_2 = ((temp_a0_2 - temp_a1_2) + 0xF) / 0x10; - temp_s1 = temp_t9_2 * 0x10; - phi_t0 = temp_t9_2; - phi_s6 = (temp_a1_2 + temp_s1) - temp_a0_2; - phi_s1 = temp_s1; + temp_a1_2 = 0x10 - var_s3; + var_s5 = temp_a1_2; + if (temp_a0 < temp_v1) { + temp_t9_2 = (s32) ((temp_a0 - temp_a1_2) + 0xF) / 16; + var_s1 = temp_t9_2 * 0x10; + var_t0 = temp_t9_2; + var_s6 = (temp_a1_2 + var_s1) - temp_a0; } else { - temp_s1_2 = temp_v1 - temp_a1_2; - phi_s6 = 0; - phi_s1_2 = temp_s1_2; - if (temp_s1_2 <= 0) { - phi_s1_2 = 0; - phi_s5 = temp_v1; + var_s1 = temp_v1 - temp_a1_2; + var_s6 = 0; + if (var_s1 <= 0) { + var_s1 = 0; + var_s5 = temp_v1; } - phi_t0 = (phi_s1_2 + 0xF) / 0x10; - phi_s1 = phi_s1_2; + var_t0 = (s32) (var_s1 + 0xF) / 16; if (sp12C->unk8 != 0) { - phi_t4 = 1; + var_t4 = 1; } else { - phi_t3 = 1; + var_t3 = 1; } } - phi_t2 = 0; - phi_t3_2 = phi_t3; - phi_t4_2 = phi_t4; - if (phi_t0 != 0) { - temp_t6 = ((temp_a2_3 - phi_s3) + 0x10) / 0x10; + var_t2 = 0; + if (var_t0 != 0) { + temp_t6 = (s32) ((temp_a2_3 - var_s3) + 0x10) / 16; if (sp130->unk1 == 0x81) { - phi_a0_2 = (temp_t6 * 9) + spEC; - phi_s0 = ((phi_t0 * 9) + 0x1F) & ~0xF; + var_s0 = ((var_t0 * 9) + 0x1F) & ~0xF; + var_a0_2 = (temp_t6 * 9) + spEC; } else { - spD8 = temp_a0_2; - sp11C = phi_t3; - sp118 = phi_t4; - spE4 = phi_t5_2; - temp_a1_3 = ((phi_t0 * 9) + 0x1F) & ~0xF; - phi_a0_2 = func_800BAD0C((temp_t6 * 9) + spEC, temp_a1_3, sp114, arg2 + 1); - phi_s0 = temp_a1_3; + spD8 = temp_a0; + sp11C = var_t3; + sp118 = var_t4; + spE4 = var_t5; + temp_a1_3 = ((var_t0 * 9) + 0x1F) & ~0xF; + var_s0 = temp_a1_3; + var_a0_2 = func_800BAD0C((temp_t6 * 9) + spEC, temp_a1_3, sp114, &synthesisState->sampleDmaIndex); } - temp_t1 = 0x540 - phi_s0; - temp_t2 = phi_a0_2 & 0xF; - phi_s2_2->unk4 = (phi_a0_2 - temp_t2) + 0x80000000; - phi_s2_2->unk0 = (((phi_s0 >> 4) & 0xFF) << 0x10) | 0x14000000 | (temp_t1 & 0xFFFF); - phi_s2_3 = phi_s2_2 + 8; - phi_t1 = temp_t1; - phi_t2 = temp_t2; - phi_t3_2 = phi_t3; - phi_t5_3 = phi_t5_2; - phi_t4_2 = phi_t4; - phi_ra = phi_t5_2 - phi_fp; + var_t1 = 0x540 - var_s0; + var_t2 = var_a0_2 & 0xF; + var_s2_2->words.w1 = (var_a0_2 - var_t2) + 0x80000000; + var_s2_2->words.w0 = (((var_s0 >> 4) & 0xFF) << 0x10) | 0x14000000 | (var_t1 & 0xFFFF); + var_s2_2 += 8; } else { - phi_s1 = 0; - phi_t1 = 0x540 - (((phi_t0 * 9) + 0x1F) & 0xFFF0); + var_s1 = 0; + var_t1 = 0x540 - (((var_t0 * 9) + 0x1F) & 0xFFF0); } - phi_t5_2 = phi_t5_3; - phi_s2_4 = phi_s2_3; - phi_t5_4 = phi_t5_3; - if (arg2->unk0 != 0) { - phi_s2_3->unk0 = 0xF000000; - phi_s2_3->unk4 = sp130->unk8 + 0x80000010; + temp_v0_4 = var_s2_2; + if (synthesisState->restart != 0) { + temp_v0_4->words.w0 = 0x0F000000; + var_s2_2 += 8; + temp_v0_4->words.w1 = sp130->unk8 + 0x80000010; sp114 = 2; - arg2->unk0 = 0; - phi_s2_4 = phi_s2_3 + 8; + synthesisState->restart = 0; } - if (phi_fp == 0) { - temp_a2_4 = phi_s1 * 2; - phi_s2_4->unk4 = (temp_a2_4 & 0xFFFF) | 0x1A00000; - phi_s2_4->unk0 = ((phi_t1 + phi_t2) & 0xFFFF) | 0x8000000; - temp_s2 = phi_s2_4 + 8; - temp_s2->unk0 = ((sp114 & 0xFF) << 0x10) | 0x1000000; - temp_s2->unk4 = arg2->unkC + 0x80000000; - spFC = phi_s3 * 2; - phi_s2_5 = temp_s2 + 8; - phi_a3 = (phi_s1 + phi_s5) - phi_s6; - phi_a2 = temp_a2_4; + if (var_fp == 0) { + var_a2 = var_s1 * 2; + var_s2_2->words.w1 = (var_a2 & 0xFFFF) | 0x01A00000; + var_s2_2->words.w0 = ((var_t1 + var_t2) & 0xFFFF) | 0x08000000; + temp_s2 = var_s2_2 + 8; + temp_s2->words.w0 = ((sp114 & 0xFF) << 0x10) | 0x01000000; + temp_s2->words.w1 = (u32) (synthesisState->synthesisBuffers + 0x80000000); + var_s2_2 = temp_s2 + 8; + spFC = var_s3 * 2; + var_a3 = (var_s1 + var_s5) - var_s6; } else { - temp_t8 = (phi_s4 + 0x1F) & ~0xF; - phi_s2_4->unk0 = ((phi_t1 + phi_t2) & 0xFFFF) | 0x8000000; - temp_a2_5 = phi_s1 * 2; - phi_s2_4->unk4 = ((temp_t8 + 0x1A0) << 0x10) | (temp_a2_5 & 0xFFFF); - temp_s2_2 = phi_s2_4 + 8; - temp_s2_2->unk0 = ((sp114 & 0xFF) << 0x10) | 0x1000000; - temp_s2_2->unk4 = arg2->unkC + 0x80000000; + temp_t8 = (var_s4 + 0x1F) & ~0xF; + var_s2_2->words.w0 = ((var_t1 + var_t2) & 0xFFFF) | 0x08000000; + var_a2 = var_s1 * 2; + var_s2_2->words.w1 = ((temp_t8 + 0x1A0) << 0x10) | (var_a2 & 0xFFFF); + temp_s2_2 = var_s2_2 + 8; + temp_s2_2->words.w0 = ((sp114 & 0xFF) << 0x10) | 0x01000000; + temp_s2_2->words.w1 = (u32) (synthesisState->synthesisBuffers + 0x80000000); temp_s2_3 = temp_s2_2 + 8; - temp_a3 = (phi_s1 + phi_s5) - phi_s6; - temp_s2_3->unk0 = ((temp_t8 + (phi_s3 * 2) + 0x1A0) & 0xFFFFFF) | 0xA000000; - temp_s2_3->unk4 = ((phi_s4 + 0x1A0) << 0x10) | ((temp_a3 * 2) & 0xFFFF); - phi_s2_5 = temp_s2_3 + 8; - phi_a3 = temp_a3; - phi_a2 = temp_a2_5; + var_a3 = (var_s1 + var_s5) - var_s6; + temp_s2_3->words.w0 = ((temp_t8 + (var_s3 * 2) + 0x1A0) & 0xFFFFFF) | 0x0A000000; + temp_s2_3->words.w1 = ((var_s4 + 0x1A0) << 0x10) | ((var_a3 * 2) & 0xFFFF); + var_s2_2 = temp_s2_3 + 8; } - temp_fp = phi_fp + phi_a3; - phi_fp = temp_fp; - phi_s2_2 = phi_s2_5; - phi_s2_6 = phi_s2_5; + var_fp += var_a3; if (sp114 != 1) { sp114 = 0; if ((sp114 ^ 2) != 0) { - if (phi_s4 != 0) { - phi_s4_2 = (phi_a3 * 2) + phi_s4; + if (var_s4 != 0) { + var_s4 += var_a3 * 2; } else { - phi_s4_2 = (phi_s3 + phi_a3) * 2; + var_s4 = (var_s3 + var_a3) * 2; } } else { - phi_s4_2 = (phi_a3 * 2) + phi_s4; + var_s4 += var_a3 * 2; } } else { - spFC = 0x20; + spFC = 0x00000020; + var_s4 = var_a2 + 0x20; sp114 = 0; - phi_s4_2 = phi_a2 + 0x20; } - phi_s4 = phi_s4_2; - if (phi_t3_2 != 0) { - phi_s2_5->unk0 = ((phi_s4_2 + 0x1A0) & 0xFFFFFF) | 0x2000000; - phi_s2_5->unk4 = (phi_t5_3 - temp_fp) * 2; - arg1->unk0 = arg1->unk0 | 0x20; - sp8C->unkB0 = sp8C->unkB0 | 0x20; - sp8C->unkB0 = sp8C->unkB0 & 0xFF7F; - spE4 = phi_t5_3; - synthesis_load_note_subs_eu(arg6, arg0, phi_a2, phi_a3); - phi_t5_4 = phi_t5_3; - phi_s2_6 = phi_s2_5 + 8; + if (var_t3 != 0) { + var_s2_2->words.w0 = ((var_s4 + 0x1A0) & 0xFFFFFF) | 0x02000000; + var_s2_2->words.w1 = (var_t5 - var_fp) * 2; + var_s2_2 += 8; + noteSubEu->unk0 = (s8) ((u8) noteSubEu->unk0 | 0x20); + sp8C->unkB0 = (u8) (sp8C->unkB0 | 0x20); + sp8C->unkB0 = (u8) (sp8C->unkB0 & 0xFF7F); + spE4 = var_t5; + func_800B6FB4(updateIndex, noteIndex); } else { - if (phi_t4_2 != 0) { - arg2->unk0 = 1; - arg2->unk8 = sp12C->unk0; + if (var_t4 != 0) { + synthesisState->restart = 1; + synthesisState->samplePosInt = sp12C->unk0; } else { - arg2->unk8 = arg2->unk8 + phi_ra; + synthesisState->samplePosInt += temp_a0; } - if (temp_fp != phi_t5_3) { + if (var_fp != var_t5) { goto loop_15; } } } - phi_s2_7 = phi_s2_6; - phi_s2_7 = phi_s2_6; if (spB0 != 1) { if (spB0 != 2) { - temp_a0_3 = arg1->unk0; - phi_t6 = (temp_a0_3 * 4) >> 0x1F; - phi_a0_4 = temp_a0_3; + var_a0 = noteSubEu->unk0; + var_t6 = (u32) (var_a0 * 4) >> 0x1F; goto block_60; } if (spAC != 0) { + temp_v0_5 = var_s2_2; if (spAC != 1) { - temp_a0_4 = arg1->unk0; - phi_v1_2 = (temp_a0_4 * 4) >> 0x1F; - phi_a0_4 = temp_a0_4; + var_a0 = noteSubEu->unk0; + var_v1_2 = (u32) (var_a0 * 4) >> 0x1F; } else { - phi_s2_6->unk0 = (((phi_t5_4 / 2) + 7) & 0xFFF8) | 0x11000000; - phi_s2_6->unk4 = ((spFC + 0x1A0) << 0x10) | ((spA0 + 0x20) & 0xFFFF); - temp_a0_5 = arg1->unk0; - phi_t6 = (temp_a0_5 * 4) >> 0x1F; - phi_s2_7 = phi_s2_6 + 8; - phi_a0_4 = temp_a0_5; + var_s2_2 += 8; + temp_v0_5->words.w0 = ((((s32) var_t5 / 2) + 7) & 0xFFF8) | 0x11000000; + temp_v0_5->words.w1 = ((spFC + 0x1A0) << 0x10) | ((spA0 + 0x20) & 0xFFFF); + var_a0 = noteSubEu->unk0; + var_t6 = (u32) (var_a0 * 4) >> 0x1F; goto block_60; } } else { - temp_s2_4 = phi_s2_6 + 8; - phi_s2_6->unk0 = (((phi_t5_4 / 2) + 7) & 0xFFF8) | 0x11000000; - phi_s2_6->unk4 = ((spFC + 0x1A0) << 0x10) | 0x20; - spA0 = phi_t5_4; - sp9E = 0x20; - temp_a0_6 = arg1->unk0; - temp_t7_3 = (temp_a0_6 * 4) >> 0x1F; - phi_v1_2 = temp_t7_3; - phi_s2_7 = temp_s2_4; - phi_a0_4 = temp_a0_6; + temp_v0_6 = var_s2_2; + var_s2_2 += 8; + temp_v0_6->words.w0 = ((((s32) var_t5 / 2) + 7) & 0xFFF8) | 0x11000000; + temp_v0_6->words.w1 = ((spFC + 0x1A0) << 0x10) | 0x20; + spA0 = var_t5; + sp9E = 0x0020; + var_a0 = noteSubEu->unk0; + temp_t7_3 = (u32) (var_a0 * 4) >> 0x1F; + var_v1_2 = temp_t7_3; if (temp_t7_3 != 0) { - temp_s2_4->unk4 = phi_t5_4 + 0x10; - temp_s2_4->unk0 = ((phi_t5_4 + 0x20) & 0xFFFFFF) | 0x2000000; - temp_a0_7 = arg1->unk0; - phi_v1_2 = (temp_a0_7 * 4) >> 0x1F; - phi_s2_7 = temp_s2_4 + 8; - phi_a0_4 = temp_a0_7; + var_s2_2->words.w1 = var_t5 + 0x10; + var_s2_2->words.w0 = ((var_t5 + 0x20) & 0xFFFFFF) | 0x02000000; + var_a0 = noteSubEu->unk0; + var_s2_2 += 8; + var_v1_2 = (u32) (var_a0 * 4) >> 0x1F; } } } else { sp9E = spFC + 0x1A0; - temp_a0_8 = arg1->unk0; - phi_t6 = (temp_a0_8 * 4) >> 0x1F; - phi_a0_4 = temp_a0_8; + var_a0 = noteSubEu->unk0; + var_t6 = (u32) (var_a0 * 4) >> 0x1F; block_60: - phi_v1_2 = phi_t6; + var_v1_2 = var_t6; } - phi_s2 = phi_s2_7; - phi_a0_3 = phi_a0_4; - phi_a0 = phi_a0_4; - if (phi_v1_2 != 0) { + if (var_v1_2 != 0) { } else { - temp_v0_3 = spAC + 1; - spAC = temp_v0_3; - if (temp_v0_3 != spB0) { + temp_v0_7 = spAC + 1; + spAC = temp_v0_7; + if (temp_v0_7 != spB0) { goto loop_6; } } - arg5 = phi_s2_7; + acmd = var_s2_2; } } - if (((phi_a0_3 * 2) >> 0x1F) == 1) { - arg1->unk0 = arg1->unk0 & 0xFFBF; - phi_v1_3 = 1; + var_v1_3 = 0; + if (((u32) (var_a0 * 2) >> 0x1F) == 1) { + var_v1_3 = 1; + noteSubEu->unk0 = (s8) ((u8) noteSubEu->unk0 & 0xFFBF); } - temp_a2_6 = arg4 * 2; - sp114 = phi_v1_3; - if ((arg1->unk3 != 0) || (arg2->unk2 != 0)) { - phi_s0_2 = 1; - } else if ((arg1->unk4 != 0) || (phi_s0_2 = 0, (arg2->unk3 != 0))) { - phi_s0_2 = 2; + temp_a2_4 = bufLen * 2; + sp114 = var_v1_3; + temp_a0_2 = final_resample(acmd, synthesisState, temp_a2_4, sp112, (s32) sp9E, var_v1_3); + if ((noteSubEu->headsetPanRight != 0) || (synthesisState->prevHeadsetPanRight != 0)) { + var_s0_2 = 1; + } else if ((noteSubEu->headsetPanLeft != 0) || (var_s0_2 = 0, (synthesisState->prevHeadsetPanLeft != 0))) { + var_s0_2 = 2; } - temp_v0_4 = func_800B86A0(func_800B8644(arg5, arg2, temp_a2_6, sp112, sp9E, phi_v1_3), arg1, arg2, arg4, 0, phi_s0_2, sp114); - phi_s2_8 = temp_v0_4; - if ((arg1->unk0 & 1) != 0) { - phi_s2_8 = func_800B8A2C(temp_v0_4, arg1, arg2, temp_a2_6, sp114, phi_s0_2); + temp_v0_8 = func_800B86A0(temp_a0_2, noteSubEu, synthesisState, bufLen, 0, var_s0_2, sp114); + var_s2 = temp_v0_8; + if ((u8) noteSubEu->unk0 & 1) { + var_s2 = note_apply_headset_pan_effects(temp_v0_8, noteSubEu, synthesisState, temp_a2_4, sp114, var_s0_2); } - return phi_s2_8; + return var_s2; } #else GLOBAL_ASM("asm/non_matchings/audio/synthesis/func_800B7C30.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void *func_800B85B4(void *arg0, void *arg1, void *arg2, s32 arg3) { - s32 temp_t0; - s32 temp_t3; - s32 temp_v1; - void *temp_a0; - void *phi_a0; - - arg0->unk0 = 0x140801A0; - arg0->unk4 = arg1->unkC + 0x80000000; - temp_a0 = arg0 + 8; - temp_t0 = arg2->unk8 & 0x3F; - temp_v1 = 0x40 - temp_t0; - arg2->unk8 = temp_t0; - phi_a0 = temp_a0; - if (temp_v1 < arg3) { - temp_t3 = ((arg3 - temp_v1) + 0x3F) / 0x40; - if (temp_t3 != 0) { - temp_a0->unk0 = ((temp_t3 & 0xFF) << 0x10) | 0x10000000 | 0x1A0; - temp_a0->unk4 = 0x2200080; - phi_a0 = temp_a0 + 8; +Acmd *load_wave_samples(Acmd *acmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad) { + s32 a3; + s32 repeats; + aLoadBuffer(acmd++, VIRTUAL_TO_PHYSICAL2(noteSubEu->sound.samples), 0x1A0, 128); + + synthesisState->samplePosInt &= 0x3f; + a3 = 64 - synthesisState->samplePosInt; + if (a3 < nSamplesToLoad) { + repeats = (nSamplesToLoad - a3 + 63) / 64; + if (repeats != 0) { + aDMEMMove2(acmd++, repeats, 0x1A0, 0x1A0 + 128, 128); } } - return phi_a0; + return acmd; } -#else -GLOBAL_ASM("asm/non_matchings/audio/synthesis/func_800B85B4.s") -#endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void *func_800B8644(void *arg0, void *arg1, s32 arg2, s32 arg3, u16 arg4, s32 arg5) { - void *temp_t0; - - arg0->unk0 = arg4 | 0x8000000; - arg0->unk4 = arg2 & 0xFFFF; - temp_t0 = arg0 + 8; - temp_t0->unk0 = ((arg5 & 0xFF) << 0x10) | 0x5000000 | (arg3 & 0xFFFF); - temp_t0->unk4 = arg1->unkC + 0x80000020; - return temp_t0 + 8; +Acmd *final_resample(Acmd *acmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags) { + aSetBuffer(acmd++, /*flags*/ 0, dmemIn, /*dmemout*/ 0, count); + aResample(acmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->finalResampleState)); + return acmd; } -#else -GLOBAL_ASM("asm/non_matchings/audio/synthesis/func_800B8644.s") -#endif #ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800B86A0(void *arg0, void *arg1, void *arg2, s32 arg3, u16 arg4, s32 arg5) { +//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c +Acmd *func_800B86A0(Acmd *acmd, struct NoteSubEu *note, struct NoteSynthesisState *synthesisState, s32 nSamples, u16 inBuf, s32 headsetPanSettings, u32 flags) { s32 sp8; s32 sp4; s32 sp0; + Acmd *temp_a0; + Acmd *temp_a0_2; + Acmd *temp_a0_3; + Acmd *var_a0; s32 temp_a2; s32 temp_a2_2; s32 temp_a2_3; @@ -1082,197 +857,131 @@ s32 func_800B86A0(void *arg0, void *arg1, void *arg2, s32 arg3, u16 arg4, s32 ar s32 temp_t5; u16 temp_v0; u16 temp_v1; - void *temp_a0; - void *temp_a0_2; - void *temp_a0_3; - void *temp_a0_4; - void *temp_a0_5; - void *phi_a0; - temp_v0 = arg2->unk10; - temp_t5 = arg3 >> 3; - temp_v1 = arg2->unk12; - sp8 = (((arg1->unk6 * 0x10) & 0xFFFF) - temp_v0) / temp_t5; - sp0 = (((arg1->unk8 * 0x10) & 0xFFFF) - temp_v1) / temp_t5; - sp4 = temp_v1; - arg2->unk10 = (temp_v0 + (spA * temp_t5)) & 0xFFFF; - arg2->unk12 = (temp_v1 + (sp2 * temp_t5)) & 0xFFFF; - if ((arg1->unk0 & 1) != 0) { - arg0->unk4 = 0x180; - arg0->unk0 = 0x2000200; - temp_a0 = arg0 + 8; - temp_a0->unk0 = (arg1->unk5 << 0x10) | 0x12000000 | ((temp_v0 & 0xFF) << 8) | (temp_v1 & 0xFF); - temp_a0->unk4 = (spA << 0x10) | (sp2 & 0xFFFF); + temp_v0 = (u16) synthesisState->curVolLeft; + temp_t5 = nSamples >> 3; + temp_v1 = (u16) synthesisState->curVolRight; + sp8 = (s32) (((note->targetVolLeft * 0x10) & 0xFFFF) - temp_v0) / temp_t5; + sp0 = (s32) (((note->targetVolRight * 0x10) & 0xFFFF) - temp_v1) / temp_t5; + sp4 = (s32) temp_v1; + synthesisState->curVolLeft = (temp_v0 + (unkspA * temp_t5)) & 0xFFFF; + synthesisState->curVolRight = (temp_v1 + (unksp2 * temp_t5)) & 0xFFFF; + if (note->unk0 & 1) { + acmd->words.w1 = 0x00000180; + acmd->words.w0 = 0x02000200; + temp_a0 = acmd + 8; + temp_a0->words.w0 = (note->reverbVol << 0x10) | 0x12000000 | ((temp_v0 & 0xFF) << 8) | (temp_v1 & 0xFF); + temp_a0->words.w1 = (unkspA << 0x10) | (unksp2 & 0xFFFF); temp_a0_2 = temp_a0 + 8; - temp_a0_2->unk0 = 0x16000000; - temp_a0_2->unk4 = (temp_v0 << 0x10) | (temp_v1 & 0xFFFF); - temp_a0_3 = temp_a0_2 + 8; - phi_a0 = temp_a0_3; - if (arg5 != 1) { - if (arg5 != 2) { - temp_a2 = arg1->unk0; - temp_a0_3->unk0 = (((arg4 >> 4) & 0xFF) << 0x10) | 0x13000000 | ((arg3 & 0xFF) << 8) | ((((temp_a2 * 0x10) >> 0x1F) & 1) * 2) | (((temp_a2 << 5) >> 0x1F) & 1); - temp_a0_3->unk4 = 0x546C849C; + temp_a0_2->words.w0 = 0x16000000; + temp_a0_2->words.w1 = (temp_v0 << 0x10) | (temp_v1 & 0xFFFF); + var_a0 = temp_a0_2 + 8; + if (headsetPanSettings != 1) { + if (headsetPanSettings != 2) { + temp_a2 = (s32) note->unk0; + var_a0->words.w0 = ((((s32) inBuf >> 4) & 0xFF) << 0x10) | 0x13000000 | ((nSamples & 0xFF) << 8) | ((((u32) (temp_a2 * 0x10) >> 0x1F) & 1) * 2) | (((u32) (temp_a2 << 5) >> 0x1F) & 1); + var_a0->words.w1 = 0x546C849C; } else { - temp_a2_2 = arg1->unk0; - temp_a0_3->unk0 = (((arg4 >> 4) & 0xFF) << 0x10) | 0x13000000 | ((arg3 & 0xFF) << 8) | ((((temp_a2_2 * 0x10) >> 0x1F) & 1) * 2) | (((temp_a2_2 << 5) >> 0x1F) & 1); - temp_a0_3->unk4 = 0x5420849C; + temp_a2_2 = (s32) note->unk0; + var_a0->words.w0 = ((((s32) inBuf >> 4) & 0xFF) << 0x10) | 0x13000000 | ((nSamples & 0xFF) << 8) | ((((u32) (temp_a2_2 * 0x10) >> 0x1F) & 1) * 2) | (((u32) (temp_a2_2 << 5) >> 0x1F) & 1); + var_a0->words.w1 = 0x5420849C; } } else { - temp_a2_3 = arg1->unk0; - temp_a0_3->unk0 = (((arg4 >> 4) & 0xFF) << 0x10) | 0x13000000 | ((arg3 & 0xFF) << 8) | ((((temp_a2_3 * 0x10) >> 0x1F) & 1) * 2) | (((temp_a2_3 << 5) >> 0x1F) & 1); - temp_a0_3->unk4 = 0x206C849C; + temp_a2_3 = (s32) note->unk0; + var_a0->words.w0 = ((((s32) inBuf >> 4) & 0xFF) << 0x10) | 0x13000000 | ((nSamples & 0xFF) << 8) | ((((u32) (temp_a2_3 * 0x10) >> 0x1F) & 1) * 2) | (((u32) (temp_a2_3 << 5) >> 0x1F) & 1); + var_a0->words.w1 = 0x206C849C; } } else { - temp_a0_4 = arg0 + 8; - arg0->unk0 = (arg1->unk5 << 0x10) | 0x12000000 | ((temp_v0 & 0xFF) << 8) | (temp_v1 & 0xFF); - arg0->unk4 = (spA << 0x10) | (sp2 & 0xFFFF); - temp_a0_4->unk0 = 0x16000000; - temp_a0_4->unk4 = (temp_v0 << 0x10) | (temp_v1 & 0xFFFF); - temp_a2_4 = arg1->unk0; - temp_a0_5 = temp_a0_4 + 8; - temp_a0_5->unk0 = (((arg4 >> 4) & 0xFF) << 0x10) | 0x13000000 | ((arg3 & 0xFF) << 8) | ((((temp_a2_4 * 0x10) >> 0x1F) & 1) * 2) | (((temp_a2_4 << 5) >> 0x1F) & 1); - temp_a0_5->unk4 = 0x546C849C; - phi_a0 = temp_a0_5; + temp_a0_3 = acmd + 8; + acmd->words.w0 = (note->reverbVol << 0x10) | 0x12000000 | ((temp_v0 & 0xFF) << 8) | (temp_v1 & 0xFF); + acmd->words.w1 = (unkspA << 0x10) | (unksp2 & 0xFFFF); + temp_a0_3->words.w0 = 0x16000000; + temp_a0_3->words.w1 = (temp_v0 << 0x10) | (temp_v1 & 0xFFFF); + temp_a2_4 = (s32) note->unk0; + var_a0 = temp_a0_3 + 8; + var_a0->words.w0 = ((((s32) inBuf >> 4) & 0xFF) << 0x10) | 0x13000000 | ((nSamples & 0xFF) << 8) | ((((u32) (temp_a2_4 * 0x10) >> 0x1F) & 1) * 2) | (((u32) (temp_a2_4 << 5) >> 0x1F) & 1); + var_a0->words.w1 = 0x546C849C; } - return phi_a0 + 8; + return var_a0 + 8; } #else GLOBAL_ASM("asm/non_matchings/audio/synthesis/func_800B86A0.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void *func_800B8A2C(void *arg0, void *arg1, void *arg2, s32 arg3, s32 arg4, s32 arg5) { - s32 temp_t0; - s32 temp_t3; - s32 temp_t3_2; - s32 temp_v0_3; - s32 temp_v0_4; - u8 temp_a3; - u8 temp_a3_2; - u8 temp_v0; - u8 temp_v0_2; - void *temp_a0; - void *temp_a0_10; - void *temp_a0_2; - void *temp_a0_3; - void *temp_a0_4; - void *temp_a0_5; - void *temp_a0_6; - void *temp_a0_7; - void *temp_a0_8; - void *temp_a0_9; - s32 phi_v0; - s32 phi_a3; - s32 phi_t3; - s32 phi_t2; - void *phi_a0; - s32 phi_v0_2; - s32 phi_a1; - void *phi_a0_2; - void *phi_a0_3; - s32 phi_t1; - - if (arg5 != 1) { - phi_t1 = 0x6C0; - if (arg5 != 2) { - return arg0; - } - temp_a3 = arg1->unk4; - temp_v0 = arg2->unk3; - arg2->unk2 = 0; - arg2->unk3 = temp_a3; - phi_v0 = temp_v0; - phi_a3 = temp_a3; - goto block_6; +Acmd *note_apply_headset_pan_effects(Acmd *acmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight) { + u16 dest; + u16 pitch; + u8 prevPanShift; + u8 panShift; + UNUSED u8 unkDebug; + + switch (leftRight) { + case 1: + dest = 0x540; + panShift = noteSubEu->headsetPanRight; + note->prevHeadsetPanLeft = 0; + prevPanShift = note->prevHeadsetPanRight; + note->prevHeadsetPanRight = panShift; + break; + case 2: + dest = 0x6C0; + panShift = noteSubEu->headsetPanLeft; + note->prevHeadsetPanRight = 0; + + prevPanShift = note->prevHeadsetPanLeft; + note->prevHeadsetPanLeft = panShift; + break; + default: + return acmd; } - temp_a3_2 = arg1->unk3; - temp_v0_2 = arg2->unk2; - arg2->unk3 = 0; - arg2->unk2 = temp_a3_2; - phi_v0 = temp_v0_2; - phi_a3 = temp_a3_2; - phi_t1 = 0x540; -block_6: - phi_a1 = phi_a3; - if (arg4 != 1) { - if (phi_v0 == 0) { - temp_a0 = arg0 + 8; - arg0->unk4 = 8; - arg0->unk0 = 0xA000200; - temp_a0_2 = temp_a0 + 8; - temp_a0->unk0 = 0x2000008; - temp_a0->unk4 = 8; - temp_a0_3 = temp_a0_2 + 8; - temp_a0_2->unk4 = 0x100010; - temp_a0_2->unk0 = 0xA000200; - temp_a0_3->unk0 = 0x15020000; - temp_t3 = (arg3 + phi_a3) - phi_v0; - temp_a0_3->unk4 = arg2->unkC + 0x80000040; - temp_a0_4 = temp_a0_3 + 8; - temp_a0_5 = temp_a0_4 + 8; - temp_v0_3 = temp_t3 & 0xFFFF; - temp_a0_4->unk4 = temp_v0_3; - temp_a0_4->unk0 = 0x8000208; - temp_a0_5->unk0 = (((arg3 << 0xF) / (temp_t3 + 8)) & 0xFFFF & 0xFFFF) | 0x5000000; - temp_a0_5->unk4 = arg2->unkC + 0x80000040; - phi_a0 = temp_a0_5 + 8; - phi_v0_2 = temp_v0_3; + + if (flags != 1) { // A_INIT? + // Slightly adjust the sample rate in order to fit a change in pan shift + if (prevPanShift == 0) { + // Kind of a hack that moves the first samples into the resample state + aDMEMMove(acmd++, 0x0200, 0x0000, 8); + aClearBuffer(acmd++, 8, 8); // Set pitch accumulator to 0 in the resample state + aDMEMMove(acmd++, 0x0200, 0x0000 + 0x10, + 0x10); // No idea, result seems to be overwritten later + + aSaveBuffer(acmd++, 0x0000, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panResampleState), sizeof(note->synthesisBuffers->panResampleState)); + + pitch = (bufLen << 0xf) / (bufLen + panShift - prevPanShift + 8); + if (pitch) {} + aSetBuffer(acmd++, 0, 0x0200 + 8, 0x0000, panShift + bufLen - prevPanShift); + aResample(acmd++, 0, pitch, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panResampleState)); } else { - if (phi_a3 == 0) { - phi_t3 = (arg3 + phi_a3) - phi_v0; - phi_t2 = ((arg3 << 0xF) / ((arg3 - phi_v0) - 4)) & 0xFFFF; + if (panShift == 0) { + pitch = (bufLen << 0xf) / (bufLen - prevPanShift - 4); } else { - temp_t3_2 = (arg3 + phi_a3) - phi_v0; - phi_t3 = temp_t3_2; - phi_t2 = ((arg3 << 0xF) / temp_t3_2) & 0xFFFF; + pitch = (bufLen << 0xf) / (bufLen + panShift - prevPanShift); } - temp_a0_6 = arg0 + 8; - temp_v0_4 = phi_t3 & 0xFFFF; - arg0->unk4 = temp_v0_4; - arg0->unk0 = 0x8000200; - temp_a0_6->unk0 = (phi_t2 & 0xFFFF) | 0x5000000; - temp_a0_6->unk4 = arg2->unkC + 0x80000040; - phi_a0 = temp_a0_6 + 8; - phi_v0_2 = temp_v0_4; + + if (1) {} + + aSetBuffer(acmd++, 0, 0x0200, 0x0000, bufLen + panShift - prevPanShift); + aResample(acmd++, 0, pitch, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panResampleState)); } - phi_a1 = phi_a3; - phi_a0_2 = phi_a0; - if (phi_v0 != 0) { - phi_a0->unk0 = (((phi_v0 >> 4) & 0xFF) << 0x10) | 0x14000000 | 0x200; - phi_a0->unk4 = arg2->unkC + 0x80000060; - temp_a0_7 = phi_a0 + 8; - temp_a0_7->unk0 = 0xA000000; - temp_a0_7->unk4 = ((phi_v0 + 0x200) << 0x10) | phi_v0_2; - phi_a0_2 = temp_a0_7; + + if (prevPanShift != 0) { + aLoadBuffer(acmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer), 0x0200, prevPanShift); + aDMEMMove(acmd++, 0x0000, 0x0200 + prevPanShift, panShift + bufLen - prevPanShift); } else { - phi_a0->unk4 = phi_v0_2 | 0x2000000; - phi_a0->unk0 = 0xA000000; + aDMEMMove(acmd++, 0x0000, 0x0200, panShift + bufLen - prevPanShift); } } else { - temp_a0_8 = arg0 + 8; - temp_t0 = arg3 & 0xFFFF; - arg0->unk4 = temp_t0; - arg0->unk0 = 0xA000200; - temp_a0_8->unk0 = 0xA000000; - temp_a0_9 = temp_a0_8 + 8; - temp_a0_8->unk4 = ((phi_a3 + 0x200) << 0x10) | temp_t0; - temp_a0_9->unk0 = 0x2000200; - temp_a0_9->unk4 = phi_a3; - phi_a0_2 = temp_a0_9; + // Just shift right + aDMEMMove(acmd++, 0x0200, 0x0000, bufLen); + aDMEMMove(acmd++, 0x0000, 0x0200 + panShift, bufLen); + aClearBuffer(acmd++, 0x0200, panShift); } - temp_a0_10 = phi_a0_2 + 8; - phi_a0_3 = temp_a0_10; - if (phi_a3 != 0) { - temp_a0_10->unk0 = (((phi_a1 >> 4) & 0xFF) << 0x10) | 0x15000000 | ((arg3 + 0x200) & 0xFFFF); - temp_a0_10->unk4 = arg2->unkC + 0x80000060; - phi_a0_3 = temp_a0_10 + 8; + + if (panShift) { + // Save excessive samples for next iteration + aSaveBuffer(acmd++, 0x0200 + bufLen, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer), panShift); } - phi_a0_3->unk0 = (((((arg3 + 0x1F) & 0xFFE0) >> 4) & 0xFF) << 0x10) | 0xC000000 | 0x7FFF; - phi_a0_3->unk4 = (phi_t1 & 0xFFFF) | 0x2000000; - return phi_a0_3 + 8; + + aMix(acmd++, /*gain*/ 0x7FFF, /*in*/ 0x0200, /*out*/ dest, ALIGN(bufLen, 5)); + + return acmd; } -#else -GLOBAL_ASM("asm/non_matchings/audio/synthesis/func_800B8A2C.s") -#endif diff --git a/src/audio/synthesis.h b/src/audio/synthesis.h index db931ae9b..ff3ac6c2c 100644 --- a/src/audio/synthesis.h +++ b/src/audio/synthesis.h @@ -1,7 +1,7 @@ #ifndef AUDIO_SYNTHESIS_H #define AUDIO_SYNTHESIS_H -//#include "internal.h" +#include "audio/internal.h" #include "PR/abi.h" #define DEFAULT_LEN_1CH 0x180 @@ -81,11 +81,17 @@ struct SynthesisReverb { #define ALIGN(val, amnt) (((val) + (1 << amnt) - 1) & ~((1 << amnt) - 1)) +void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex, s32 reverbIndex); u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen); Acmd *synthesis_load_reverb_ring_buffer(Acmd*, u16, u16, s32, s32); Acmd *synthesis_save_reverb_ring_buffer(Acmd*, u16, u16, s32, s32); -Acmd *func_800B7304(Acmd*, s32, s16, s16); -Acmd *func_800B7630(Acmd*, s16, s16); +void func_800B6FB4(s32 updateIndexStart, s32 noteIndex); +void synthesis_load_note_subs_eu(s32 updateIndex); +Acmd *synthesis_resample_and_mix_reverb(Acmd*, s32, s16, s16); +Acmd *synthesis_load_reverb_samples(Acmd*, s16, s16); +Acmd *load_wave_samples(Acmd *acmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad); +Acmd *final_resample(Acmd *acmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags); +Acmd *note_apply_headset_pan_effects(Acmd *acmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight); extern struct AudioBufferParametersEU gAudioBufferParameters; extern s32 gMaxSimultaneousNotes; @@ -93,9 +99,15 @@ extern s32 gMaxSimultaneousNotes; extern struct SynthesisReverb gSynthesisReverbs[4]; extern s8 gNumSynthesisReverbs; extern struct NoteSubEu *gNoteSubsEu; -extern f32 gLeftVolRampings; -//extern f32 gRightVolRampings[3][1024]; -//extern f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above -//extern f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above +/* +SO +gLeftVolRampings is almost certainly gAudioSessionPool (D_803AFBC8) in disguise, but since +synthesis' ro/data has already been broken out it'll be very hard to fix that. + +extern f32 gLeftVolRampings[3][1024]; +extern f32 gRightVolRampings[3][1024]; +extern f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above +extern f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above +*/ #endif // AUDIO_SYNTHESIS_H |
