diff --git a/.vscode/settings.json b/.vscode/settings.json index 1f40419c..c5d8e7b9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -80,6 +80,14 @@ "util": "c", "variant": "c", "chrono": "c", + "optional": "c", + "istream": "c", + "ostream": "c", + "ratio": "c", + "system_error": "c", + "functional": "c", + "tuple": "c", + "type_traits": "c", "ast_allies.h": "c", "ast_font.h": "c", "fox_std_lib_assets.h": "c", diff --git a/include/sf64audio_provisional.h b/include/sf64audio_provisional.h index 482fbf76..8e29c27f 100644 --- a/include/sf64audio_provisional.h +++ b/include/sf64audio_provisional.h @@ -347,23 +347,24 @@ typedef struct { /* 0x00 */ u8 asByte; } action; /* 0x01 */ u8 state; - /* 0x02 */ u8 envIndex; + /* 0x02 */ s16 envIndex; /* 0x04 */ s16 delay; /* 0x08 */ f32 sustain; /* 0x0C */ f32 velocity; /* 0x10 */ f32 fadeOutVel; /* 0x14 */ f32 current; /* 0x18 */ f32 target; - /* 0x1C */ EnvelopePoint* envelope; -} AdsrState; // size = 0x20 + /* 0x1C */ char pad[4]; + /* 0x20 */ EnvelopePoint* envelope; +} AdsrState; // size = 0x24 typedef struct { + /* 0x00 */ u8 stereoHeadsetEffects : 1; + /* 0x00 */ u8 usesHeadsetPanEffects : 1; /* 0x00 */ u8 unused : 2; /* 0x00 */ u8 bit2 : 2; /* 0x00 */ u8 strongRight : 1; /* 0x00 */ u8 strongLeft : 1; - /* 0x00 */ u8 stereoHeadsetEffects : 1; - /* 0x00 */ u8 usesHeadsetPanEffects : 1; } StereoData; // size = 0x1 typedef union { @@ -524,9 +525,9 @@ typedef struct { /* 0x10 */ f32 rate; /* 0x14 */ u8 active; /* 0x16 */ u16 rateChangeTimer; - // /* 0x18 */ u16 depthChangeTimer; - // /* 0x1A */ u16 delay; -} VibratoState; // size = 0x18 + /* 0x18 */ u16 depthChangeTimer; + /* 0x1A */ u16 delay; +} VibratoState; // size = 0x1C typedef struct { /* 0x00 */ u8 priority; @@ -544,9 +545,9 @@ typedef struct { /* 0x18 */ struct SequenceLayer* wantedParentLayer; /* 0x1C */ NoteAttributes attributes; /* 0x28 */ AdsrState adsr; - /* 0x48 */ Portamento portamento; - /* 0x58 */ VibratoState vibratoState; -} NotePlaybackState; // size = 0x70 + /* 0x4C */ Portamento portamento; + /* 0x5C */ VibratoState vibratoState; +} NotePlaybackState; // size = 0x78 typedef struct { struct { @@ -580,7 +581,7 @@ typedef struct Note { /* 0x00 */ AudioListItem listItem; /* 0x10 */ NoteSynthesisState synthesisState; /* 0x30 */ NotePlaybackState playbackState; - /* 0xA0 */ char padA0[0x10]; + /* 0xA8 */ char padA0[0x8]; /* 0xB0 */ NoteSubEu noteSubEu; } Note; // size = 0xC0 @@ -1032,6 +1033,16 @@ Acmd* func_8000B480(Acmd* aList, NoteSynthesisState* synthState, s32 size, u16 p Acmd* func_8000B51C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 aiBufLen, u16 dmemSrc, s32 delaySide, s32 flags); Acmd* func_8000B98C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 size, s32 flags, s32 delaySide); +void func_80013400(SequenceChannel* channel, s32 updateVolume); +void func_800135A8(SequencePlayer* seqplayer); +f32 func_80013708(Portamento* portamento); +s16 func_800137DC(VibratoState* vibrato); +f32 func_80013820(VibratoState* vibrato); +void func_80013A18(Note* note); +void func_80013A84(Note* note); +void func_80013B6C(AdsrState* adsr, EnvelopePoint* envelope, s16* arg2); +f32 func_80013B90(AdsrState* adsr); + void AudioHeap_ResetLoadStatus(void); void AudioHeap_DiscardFont(s32 fontId); void AudioHeap_DiscardSequence(s32 seqId); @@ -1118,43 +1129,64 @@ s32 AudioLoad_AddToSampleSet(Sample* sample, s32 numSamples, Sample** sampleSet) s32 AudioLoad_GetSamplesForFont(s32 fontId, Sample** sampleSet); -void func_80011890(Note*, NoteAttributes*); -void func_80011C58(Note*, f32); +void func_80011890(Note* note, NoteAttributes* noteAttr); +void func_80011C58(Note* note, f32); +TunedSample* func_80011D10(Instrument* instrument, s32 arg1); Instrument* Audio_GetInstrument(s32, s32); Drum* Audio_GetDrum(s32, s32); -void func_80011EB8(Note*); -void func_80011F4C(Note*); -void func_80012438(SequenceLayer*, s32); -void func_8001266C(SequenceLayer*); -void func_8001268C(SequenceLayer*); -s32 func_800126AC(Note*, SequenceLayer*, s32); -void func_800127B0(Note*, SequenceLayer*); -void func_80012854(AudioListItem*); -void func_80012864(NotePool*); +void func_80011EB8(Note* note); +void func_80011F4C(Note* note); +void func_80011FA8(void); +void func_80012438(SequenceLayer* layer, s32); +void func_8001266C(SequenceLayer* layer); +void func_8001268C(SequenceLayer* layer); +s32 func_800126AC(Note* note, SequenceLayer* layer, s32); +void func_800127B0(Note* note, SequenceLayer* layer); +void func_80012854(AudioListItem* item); +void func_80012864(NotePool* pool); void func_800128B4(void); -void func_80012964(NotePool*); -void func_80012AC4(NotePool*, s32); -void func_80012C00(AudioListItem*, AudioListItem*); -void func_80012C40(Note*); -Note* func_80012C6C(AudioListItem*, s32); -void func_80012CEC(Note *, SequenceLayer *); -void func_80012E28(Note *, SequenceLayer *); -void func_80012E5C(Note* , SequenceLayer *); -Note *func_80012E88(NotePool* , SequenceLayer *); -Note *func_80012ED4(NotePool* , SequenceLayer *); -Note *func_80012F24(NotePool* , SequenceLayer *); -Note *func_8001301C(SequenceLayer *); +void func_80012964(NotePool* pool); +void func_80012AC4(NotePool* pool, s32); +void func_80012C00(AudioListItem* item1, AudioListItem* item2); +void func_80012C40(Note* note); +Note* func_80012C6C(AudioListItem* item, s32); +void func_80012CEC(Note* note, SequenceLayer* layer); +void func_80012E28(Note* note, SequenceLayer* layer); +void func_80012E5C(Note* note, SequenceLayer* layer); +Note *func_80012E88(NotePool* pool, SequenceLayer* layer); +Note *func_80012ED4(NotePool* pool, SequenceLayer* layer); +Note *func_80012F24(NotePool* pool, SequenceLayer* layer); +Note *func_8001301C(SequenceLayer* layer); void func_800132E8(void); -void func_800144E4(SequencePlayer*); -void func_800145BC(AudioListItem*, AudioListItem*); -void func_8001678C(s32); -void func_80016804(s32); +void func_80013EA0(SequenceChannel* channel); +s32 func_80013FC4(SequenceChannel* channel, s32 arg1); +void func_800140D0(SequenceLayer* layer); +void func_8001410C(SequenceChannel* channel, s32 arg1); +void func_8001415C(SequenceChannel* channel); +SequenceChannel* func_800141C8(void); +void func_80014244(SequencePlayer* seqPlayer, u16 arg1); +void func_80014370(SequencePlayer* seqPlayer, u16 arg1); +void func_80014440(SequencePlayer* seqPlayer, u8 arg1, u8* arg2); +void func_800144E4(SequencePlayer* seqPlayer); +void func_800145BC(AudioListItem* list, AudioListItem* item); +void* func_800145FC(AudioListItem* list); +void func_8001463C(void); +u8 func_800146C0(SeqScriptState* state); +s16 func_800146D4(SeqScriptState* state); +u16 func_80014704(SeqScriptState* state); +void func_80014748(SequenceLayer* layer); +u8 func_800152C0(SequenceChannel* channel, u8 arg1, Instrument** instrument, AdsrSettings* adsrSettings); +void func_80015330(SequenceChannel* channel, u8 arg1); +// void func_800153C4(SequenceChannel* channel, u8 arg1); +void func_800153E8(SequenceChannel* channel); +void func_80015FD4(SequencePlayer* seqPlayer); +void func_8001678C(s32 arg0); +void func_80016804(s32 arg0); void func_800168BC(void); - SPTask* AudioThread_CreateTask(void); void AudioThread_ScheduleProcessCmds(void); u32 AudioThread_GetAsyncLoadStatus(u32 *); @@ -1405,6 +1437,30 @@ extern OSMesg sThreadCmdProcMsg[4]; extern OSMesg sAudioUnkMsg[1]; extern OSMesg sAudioResetMsg[1]; +// wave_samples +extern s16 gSawtoothWaveSample[]; +extern s16 gTriangleWaveSample[]; +extern s16 gSineWaveSample[]; +extern s16 gSquareWaveSample[]; +extern s16 gWhiteNoiseSample[]; +extern s16 gUnkSample[]; +extern s16* gWaveSamples[]; + +// note_data +extern f32 gBendPitchOneOctaveFrequencies[]; +extern f32 gBendPitchTwoSemitonesFrequencies[]; +extern f32 gPitchFrequencies[]; +extern u8 gDefaultShortNoteVelocityTable[]; +extern u8 gDefaultShortNoteGateTimeTable[]; +extern u16 gHaasEffectDelaySizes[64]; +extern EnvelopePoint gDefaultEnvelope[]; +extern NoteSubEu gZeroNoteSub; +extern NoteSubEu gDefaultNoteSub; +extern s16 D_800DD200[]; +extern f32 gHeadsetPanVolume[]; +extern f32 gStereoPanVolume[]; +extern f32 gDefaultPanVolume[]; + typedef enum { SEQ_ID_0, SEQ_ID_1, diff --git a/include/variables.h b/include/variables.h index 95bf1fd2..e03cbbfd 100644 --- a/include/variables.h +++ b/include/variables.h @@ -246,28 +246,6 @@ extern Gfx D_Gfx_800DBAA0[]; extern Gfx D_Gfx_800DAC20[]; extern Gfx D_Gfx_800D9688[]; -// wave_samples -extern s16 gSawtoothWaveSample[]; -extern s16 gTriangleWaveSample[]; -extern s16 gSineWaveSample[]; -extern s16 gSquareWaveSample[]; -extern s16 gWhiteNoiseSample[]; -extern s16 gUnkSample[]; -extern s16* gWaveSamples[]; -// note_data -extern f32 gBendPitchOneOctaveFrequencies[]; -extern f32 gBendPitchTwoSemitonesFrequencies[]; -extern f32 gPitchFrequencies[]; -extern u8 gDefaultShortNoteVelocityTable[]; -extern u8 gDefaultShortNoteGateTimeTable[]; -extern u16 gHaasEffectDelaySizes[64]; -// extern EnvelopePoint gDefaultEnvelope[]; -// extern NoteUnkStruct gZeroNoteSub; -// extern NoteUnkStruct gDefaultNoteSub; -extern s16 D_800DD200[]; -extern f32 gHeadsetPanVolume[]; -extern f32 gStereoPanVolume[]; -extern f32 gDefaultPanVolume[]; #endif // VARIABLES_H diff --git a/src/main/audio_effects.c b/src/main/audio_effects.c index e8a154c1..4c6c1b85 100644 --- a/src/main/audio_effects.c +++ b/src/main/audio_effects.c @@ -3,20 +3,276 @@ static char devstr[] = "Audio:Envp: overflow %f\n"; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_effects/func_80013400.s") +void func_80013400(SequenceChannel* channel, s32 updateVolume) { + s32 i; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_effects/func_800135A8.s") + if (channel->changes.s.volume || updateVolume) { + f32 channelVolume = channel->volume * channel->volumeMod * channel->seqPlayer->appliedFadeVolume; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_effects/func_80013708.s") + if (channel->seqPlayer->muted && (channel->muteBehavior & 0x20)) { + channelVolume = channel->seqPlayer->muteVolumeMod * channelVolume; + } + channel->appliedVolume = SQ(channelVolume); + } + if (channel->changes.s.pan) { + channel->pan = channel->newPan * channel->panChannelWeight; + } + for (i = 0; i < 4; i++) { + SequenceLayer* layer = channel->layers[i]; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_effects/func_800137DC.s") + if ((layer != NULL) && layer->enabled && (layer->note != NULL)) { + if (layer->ignoreDrumPan) { + layer->noteFreqMod = layer->freqMod * channel->freqMod; + layer->noteVelocity = layer->velocitySquare * channel->appliedVolume; + layer->notePan = (channel->pan + (layer->pan * (0x80 - channel->panChannelWeight))) >> 7; + layer->ignoreDrumPan = false; + } else { + if (channel->changes.s.freqMod) { + layer->noteFreqMod = layer->freqMod * channel->freqMod; + } + if (channel->changes.s.volume || updateVolume) { + layer->noteVelocity = layer->velocitySquare * channel->appliedVolume; + } + if (channel->changes.s.pan) { + layer->notePan = (channel->pan + (layer->pan * (0x80 - channel->panChannelWeight))) >> 7; + } + } + } + } + channel->changes.asByte = 0; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_effects/func_80013820.s") +void func_800135A8(SequencePlayer* seqplayer) { + s32 i; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_effects/func_80013A18.s") + if (seqplayer->fadeTimer != 0) { + seqplayer->fadeVolume += seqplayer->fadeVelocity; + seqplayer->recalculateVolume = true; + if (seqplayer->fadeVolume > 1.0f) { + seqplayer->fadeVolume = 1.0f; + } + if (seqplayer->fadeVolume < 0.0f) { + seqplayer->fadeVolume = 0.0f; + } + seqplayer->fadeTimer--; + if ((seqplayer->fadeTimer == 0) && (seqplayer->state == 2)) { + func_800144E4(seqplayer); + return; + } + } + if (seqplayer->recalculateVolume) { + seqplayer->appliedFadeVolume = seqplayer->fadeVolume * seqplayer->fadeVolumeMod; + } + for (i = 0; i < 16; i++) { + if ((((u32) seqplayer->channels[i] != (u32) &gSeqChannelNone) == 1) && (seqplayer->channels[i]->enabled == 1)) { + func_80013400(seqplayer->channels[i], seqplayer->recalculateVolume); + } + } + seqplayer->recalculateVolume = false; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_effects/func_80013A84.s") +f32 func_80013708(Portamento* portamento) { + u32 temp; + f32 temp2; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_effects/func_80013B6C.s") + portamento->cur += portamento->speed; + temp = portamento->cur; + if (temp > 127) { + temp = 127; + } + temp2 = 1.0f + ((gBendPitchOneOctaveFrequencies[0x80 + temp] - 1.0f) * portamento->extent); + return temp2; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_effects/func_80013B90.s") +s16 func_800137DC(VibratoState* vibrato) { + s32 index; + + vibrato->time += (s32) vibrato->rate; + index = (vibrato->time >> 0xA) & 0x3F; + return vibrato->curve[index] >> 8; +} + +f32 func_80013820(VibratoState* vibrato) { + s32 ret; + f32 temp; + f32 temp2; + + if (vibrato->delay != 0) { + vibrato->delay--; + return 1.0f; + } + if (vibrato->depthChangeTimer) { + if (vibrato->depthChangeTimer == 1) { + vibrato->depth = (s32) vibrato->channel->vibratoDepthTarget; + } else { + vibrato->depth += + ((s32) vibrato->channel->vibratoDepthTarget - vibrato->depth) / (s32) vibrato->depthChangeTimer; + } + vibrato->depthChangeTimer--; + } else if (vibrato->channel->vibratoDepthTarget != (s32) vibrato->depth) { + if ((vibrato->depthChangeTimer = vibrato->channel->vibratoDepthChangeDelay) == 0) { + vibrato->depth = (s32) vibrato->channel->vibratoDepthTarget; + } + } + if (vibrato->rateChangeTimer) { + if (vibrato->rateChangeTimer == 1) { + vibrato->rate = (s32) vibrato->channel->vibratoRateTarget; + } else { + vibrato->rate += + ((s32) vibrato->channel->vibratoRateTarget - vibrato->rate) / (s32) vibrato->rateChangeTimer; + } + vibrato->rateChangeTimer--; + } else if (vibrato->channel->vibratoRateTarget != (s32) vibrato->rate) { + if ((vibrato->rateChangeTimer = vibrato->channel->vibratoRateChangeDelay) == 0) { + vibrato->rate = (s32) vibrato->channel->vibratoRateTarget; + } + } + if (vibrato->depth == 0.0f) { + return 1.0f; + } + ret = func_800137DC(vibrato); + temp = vibrato->depth / 4096.0f; + temp2 = 1.0f + temp * (gBendPitchOneOctaveFrequencies[0x80 + ret] - 1.0f); + return temp2; +} + +void func_80013A18(Note* note) { + if (note->playbackState.portamento.mode != 0) { + note->playbackState.portamentoFreqMod = func_80013708(¬e->playbackState.portamento); + } + if ((note->playbackState.vibratoState.active != 0) && (note->playbackState.parentLayer != NO_LAYER)) { + note->playbackState.vibratoFreqMod = func_80013820(¬e->playbackState.vibratoState); + } +} + +void func_80013A84(Note* note) { + NotePlaybackState* temp_v0_3 = ¬e->playbackState; + VibratoState* temp_v1 = &temp_v0_3->vibratoState; + + temp_v1->active = 1; + temp_v1->time = 0; + temp_v0_3->vibratoFreqMod = 1.0f; + temp_v0_3->portamentoFreqMod = 1.0f; + + temp_v1->curve = gWaveSamples[2]; + + temp_v1->channel = temp_v0_3->parentLayer->channel; + + if ((temp_v1->depthChangeTimer = temp_v1->channel->vibratoDepthChangeDelay) == 0) { + temp_v1->depth = (s32) temp_v1->channel->vibratoDepthTarget; + } else { + temp_v1->depth = (s32) temp_v1->channel->vibratoDepthStart; + } + if ((temp_v1->rateChangeTimer = temp_v1->channel->vibratoRateChangeDelay) == 0) { + temp_v1->rate = (s32) temp_v1->channel->vibratoRateTarget; + } else { + temp_v1->rate = (s32) temp_v1->channel->vibratoRateStart; + } + + temp_v1->delay = temp_v1->channel->vibratoDelay; + temp_v0_3->portamento = temp_v0_3->parentLayer->portamento; +} + +void func_80013B6C(AdsrState* adsr, EnvelopePoint* envelope, s16* arg2) { + adsr->action.asByte = 0; + adsr->state = 0; + adsr->delay = 0; + adsr->envelope = envelope; + adsr->sustain = 0.0f; + adsr->current = 0.0f; +} + +f32 func_80013B90(AdsrState* adsr) { + u8 action = adsr->action.asByte; + u8 state = adsr->state; + + switch (state) { + case 0: + return 0.0f; + case 1: + if (action & 0x40) { + adsr->state = 5; + break; + } + case 2: + adsr->envIndex = 0; + adsr->state = 3; + case_3: + case 3: + adsr->delay = adsr->envelope[adsr->envIndex].delay; + switch (adsr->delay) { + case 0: + adsr->state = 0; + break; + case -1: + adsr->state = 5; + break; + case -2: + adsr->envIndex = adsr->envelope[adsr->envIndex].arg; + goto case_3; + case -3: + adsr->state = 1; + break; + default: + if (adsr->delay >= 4) { + adsr->delay = + (adsr->delay * gAudioBufferParams.ticksPerUpdate / gAudioBufferParams.specUnk4) / 4; + } + if (adsr->delay == 0) { + adsr->delay = 1; + } + + adsr->target = adsr->envelope[adsr->envIndex].arg / 32767.0f; + adsr->target = SQ(adsr->target); + adsr->velocity = (adsr->target - adsr->current) / adsr->delay; + adsr->state = 4; + adsr->envIndex++; + break; + } + if (adsr->state != 4) { + break; + } + case 4: + adsr->delay -= 1; + adsr->current += adsr->velocity; + if (adsr->delay <= 0) { + adsr->state = 3; + } + break; + case 6: + case 7: + adsr->current -= adsr->fadeOutVel; + if ((adsr->sustain != 0.0f) && (state == 6)) { + if (adsr->current < adsr->sustain) { + adsr->current = adsr->sustain; + adsr->delay = 0x80; + adsr->state = 8; + } + } else if (adsr->current < 0.00001f) { + adsr->current = 0.0f; + adsr->state = 0; + } + break; + case 8: + adsr->delay--; + if (adsr->delay == 0) { + adsr->state = 7; + } + break; + } + if (action & 0x20) { + adsr->state = 6; + adsr->action.asByte = action & ~0x20; + } + if (action & 0x10) { + adsr->state = 7; + adsr->action.asByte = action & ~0x10; + } + if (adsr->current < 0.0f) { + return 0.0f; + } + if (adsr->current > 1.0f) { + return 1.0f; + } + return adsr->current; +} diff --git a/src/main/audio_playback.c b/src/main/audio_playback.c index ba146d8d..0b85ed63 100644 --- a/src/main/audio_playback.c +++ b/src/main/audio_playback.c @@ -32,62 +32,767 @@ static char devstr24[] = "Audio: C-Alloc : lowerPrio is NULL\n"; static char devstr25[] = "Intterupt UseStop %d (Kill %d)\n"; static char devstr26[] = "Intterupt RelWait %d (Kill %d)\n"; static char devstr27[] = "Drop Voice (Prio %x)\n"; -// static char devstr28[] = ""; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80011890.s") +void func_80011890(Note* note, NoteAttributes* noteAttr) { + NoteSubEu* temp_v0; + f32 var_fa0; + f32 var_fa1; + f32 var_fv1; + s32 temp_t0; + s32 var_a0; + s32 var_a0_2; + s32 var_a1; + u8 sp27; + u8 sp26; + Stereo sp24; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80011C58.s") + func_80011C58(note, noteAttr->freqMod); + temp_v0 = ¬e->noteSubEu; + var_fv1 = noteAttr->velocity; + sp27 = noteAttr->pan; + sp26 = noteAttr->reverb; + sp24 = noteAttr->stereo; + sp27 &= 0x7F; + if ((temp_v0->bitField0.stereoHeadsetEffects) && (gAudioSoundMode == 1)) { + var_a0 = sp27 >> 1; + if (var_a0 >= 0x40) { + var_a0 = 0x3F; + } + temp_v0->unk_04 = gHaasEffectDelaySizes[var_a0]; + temp_v0->unk_03 = gHaasEffectDelaySizes[63 - var_a0]; + temp_v0->bitField0.stereoStrongRight = 0; + temp_v0->bitField0.stereoStrongLeft = 0; + temp_v0->bitField0.usesHeadsetPanEffects = 1; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80011D10.s") + var_fa0 = gHeadsetPanVolume[sp27]; + var_fa1 = gHeadsetPanVolume[127 - sp27]; + } else if (temp_v0->bitField0.stereoHeadsetEffects && (gAudioSoundMode == 0)) { + temp_v0->unk_03 = 0; + temp_v0->unk_04 = 0; + temp_v0->bitField0.usesHeadsetPanEffects = 0; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/Audio_GetInstrument.s") + var_fa0 = gStereoPanVolume[sp27]; + var_fa1 = gStereoPanVolume[127 - sp27]; + var_a0_2 = 0; + var_a1 = 0; + if (sp27 < 0x20) { + var_a1 = 1; + } else if (sp27 > 0x60) { + var_a0_2 = 1; + } + temp_v0->bitField0.stereoStrongRight = var_a0_2; + temp_v0->bitField0.stereoStrongLeft = var_a1; + switch (sp24.s.bit2) { + case 0: + temp_v0->bitField0.stereoStrongRight = sp24.s.strongRight; + temp_v0->bitField0.stereoStrongLeft = sp24.s.strongLeft; + break; + case 1: + break; + case 2: + temp_v0->bitField0.stereoStrongRight = sp24.s.strongRight | var_a0_2; + temp_v0->bitField0.stereoStrongLeft = sp24.s.strongLeft | var_a1; + break; + case 3: + temp_v0->bitField0.stereoStrongRight = sp24.s.strongRight ^ var_a0_2; + temp_v0->bitField0.stereoStrongLeft = sp24.s.strongLeft ^ var_a1; + break; + } + } else if (gAudioSoundMode == 3) { + var_fa0 = 0.707f; + var_fa1 = 0.707f; + } else { + var_fa0 = gDefaultPanVolume[sp27]; + var_fa1 = gDefaultPanVolume[127 - sp27]; + } + if (var_fv1 < 0.0f) { + var_fv1 = 0.0f; + } + if (var_fv1 > 1.0f) { + var_fv1 = 1.0f; + } + temp_v0->unk_06 = (s32) (var_fv1 * var_fa0 * 4095.999f); + temp_v0->unk_08 = (s32) (var_fv1 * var_fa1 * 4095.999f); + temp_v0->unk_02 = noteAttr->gain; + if (temp_v0->unk_05 != sp26) { + temp_v0->unk_05 = sp26; + temp_v0->bitField0.unused = 1; + } else if (temp_v0->bitField0.needsInit) { + temp_v0->bitField0.unused = 1; + } else { + temp_v0->bitField0.unused = 0; + } +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/Audio_GetDrum.s") +void func_80011C58(Note* note, f32 arg1) { + NoteSubEu* noteSub = ¬e->noteSubEu; + f32 var_fv0; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80011EB8.s") + if (arg1 < 2.0f) { + noteSub->bitField1.hasTwoParts = 0; + if (arg1 > 1.99998f) { + var_fv0 = 1.99998f; + } else { + var_fv0 = arg1; + } + } else { + noteSub->bitField1.hasTwoParts = 1; + if (arg1 > 3.99996f) { + var_fv0 = 1.99998f; + } else { + var_fv0 = arg1 * 0.5f; + } + } + note->noteSubEu.unk_0A = (s32) (var_fv0 * 32768.0f); +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80011F4C.s") +TunedSample* func_80011D10(Instrument* instrument, s32 arg1) { + TunedSample* sample; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80011FA8.s") + if (arg1 < instrument->normalRangeLo) { + sample = &instrument->lowPitchTunedSample; + } else if (arg1 <= instrument->normalRangeHi) { + sample = &instrument->normalPitchTunedSample; + } else { + sample = &instrument->highPitchTunedSample; + } + return sample; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012438.s") +Instrument* Audio_GetInstrument(s32 arg0, s32 arg1) { + Instrument* temp_v1; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_8001266C.s") + if ((gFontLoadStatus[arg0] < 2) != 0) { + D_80155D88 = arg0 + 0x10000000; + return NULL; + } + if (arg1 >= gSoundFontList[arg0].numInstruments) { + D_80155D88 = (arg0 << 8) + arg1 + 0x03000000; + return NULL; + } + temp_v1 = gSoundFontList[arg0].instruments[arg1]; + if (temp_v1 == NULL) { + D_80155D88 = (arg0 << 8) + arg1 + 0x01000000; + return temp_v1; + } + return temp_v1; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_8001268C.s") +Drum* Audio_GetDrum(s32 arg0, s32 arg1) { + Drum* temp; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_800126AC.s") + if ((gFontLoadStatus[arg0] < 2) != 0) { + D_80155D88 = arg0 + 0x10000000; + return NULL; + } + if (arg1 >= gSoundFontList[arg0].numDrums) { + D_80155D88 = (arg0 << 8) + arg1 + 0x04000000; + return NULL; + } + if ((u32) gSoundFontList[arg0].drums < 0x80000000U) { + return NULL; + } + temp = gSoundFontList[arg0].drums[arg1]; + if (gSoundFontList[arg0].drums[arg1] == NULL) { + D_80155D88 = (arg0 << 8) + arg1 + 0x05000000; + } + return temp; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_800127B0.s") +void func_80011EB8(Note* note) { + if (note->playbackState.parentLayer->adsr.decayIndex == 0) { + func_80013B6C(¬e->playbackState.adsr, note->playbackState.parentLayer->channel->adsr.envelope, + ¬e->playbackState.adsrVolModUnused); + } else { + func_80013B6C(¬e->playbackState.adsr, note->playbackState.parentLayer->adsr.envelope, + ¬e->playbackState.adsrVolModUnused); + } + note->playbackState.adsr.state = 1; + note->noteSubEu = gDefaultNoteSub; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012854.s") +void func_80011F4C(Note* note) { + if (note->noteSubEu.bitField0.needsInit == 1) { + note->noteSubEu.bitField0.needsInit = 0; + } + note->playbackState.priority = 0; + note->playbackState.unk_04 = 0; + note->noteSubEu.bitField0.enabled = 0; + note->playbackState.parentLayer = NO_LAYER; + note->playbackState.prevParentLayer = NO_LAYER; + note->noteSubEu.bitField0.finished = 0; + note->playbackState.adsr.state = 0; + note->playbackState.adsr.current = 0.0f; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012864.s") +void func_80011FA8(void) { + s32 pad2; + s32 pad; + Note* temp_s1; + NotePlaybackState* var_s0; + NoteSubEu* noteSub; + NoteAttributes* attr; + s32 i; + NoteAttributes sp70; + u8 sp6F; + f32 temp_fs0; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_800128B4.s") + for (i = 0; i < gNumNotes; i++) { + temp_s1 = &gNotes[i]; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012964.s") + var_s0 = &temp_s1->playbackState; + if ((var_s0->parentLayer != NO_LAYER)) { + if ((u32) var_s0->parentLayer < 0x7FFFFFFF) { + continue; + } -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012AC4.s") + if ((temp_s1 != var_s0->parentLayer->note) && (var_s0->unk_04 == 0)) { + var_s0->adsr.action.asByte |= 0x10; + var_s0->adsr.fadeOutVel = gAudioBufferParams.ticksPerUpdateInv; + var_s0->priority = 1; + var_s0->unk_04 = 2; + goto block_21; + } else { + if ((var_s0->parentLayer->enabled) || (var_s0->unk_04 != 0) || (var_s0->priority <= 0)) { + if (var_s0->parentLayer->channel->seqPlayer == NULL) { + func_8001415C(var_s0->parentLayer->channel); + var_s0->priority = 1; + var_s0->unk_04 = 1; + continue; + } + if (!(var_s0->parentLayer->channel->seqPlayer->muted && + (var_s0->parentLayer->channel->muteBehavior & 0x40))) { + goto block_21; + } + } + func_8001268C(var_s0->parentLayer); + func_80012C40(temp_s1); + func_80012C00(&temp_s1->listItem.pool->decaying, &temp_s1->listItem); + var_s0->priority = 1; + var_s0->unk_04 = 2; + } + } else if ((var_s0->unk_04 == 0) && (var_s0->priority > 0)) { + continue; + } + block_21: -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012C00.s") + if (var_s0->priority != 0) { + if (1) {} + noteSub = &temp_s1->noteSubEu; + if ((var_s0->unk_04 > 0) || noteSub->bitField0.finished) { + if ((var_s0->adsr.state == 0) || noteSub->bitField0.finished) { + if (var_s0->wantedParentLayer != NO_LAYER) { + func_80011F4C(temp_s1); + if (var_s0->wantedParentLayer->channel != NULL) { + func_80012CEC(temp_s1, var_s0->wantedParentLayer); + func_80013A84(temp_s1); + func_80012C40(temp_s1); + func_800145BC(&temp_s1->listItem.pool->active, &temp_s1->listItem); + var_s0->wantedParentLayer = NO_LAYER; + } else { + func_80011F4C(temp_s1); + func_80012C40(temp_s1); + func_800145BC(&temp_s1->listItem.pool->disabled, &temp_s1->listItem); + var_s0->wantedParentLayer = NO_LAYER; + goto next; + } + } else { + func_80011F4C(temp_s1); + func_80012C40(temp_s1); + func_800145BC(&temp_s1->listItem.pool->disabled, &temp_s1->listItem); + goto next; + } + } + } else if (var_s0->adsr.state == 0) { + func_80011F4C(temp_s1); + func_80012C40(temp_s1); + func_800145BC(&temp_s1->listItem.pool->disabled, &temp_s1->listItem); + goto next; + } -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012C40.s") + temp_fs0 = func_80013B90(&var_s0->adsr); + func_80013A18(temp_s1); + attr = &var_s0->attributes; + if ((var_s0->unk_04 == 1) || (var_s0->unk_04 == 2)) { -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012C6C.s") + sp70.freqMod = attr->freqMod; + sp70.velocity = attr->velocity; + sp70.pan = attr->pan; + sp70.reverb = attr->reverb; + sp70.stereo = attr->stereo; + sp70.gain = attr->gain; + sp6F = noteSub->bitField1.bookOffset; + } else { + sp70.freqMod = var_s0->parentLayer->noteFreqMod; + sp70.velocity = var_s0->parentLayer->noteVelocity; + sp70.pan = var_s0->parentLayer->notePan; + sp70.stereo = var_s0->parentLayer->stereo; + sp70.reverb = var_s0->parentLayer->channel->targetReverbVol; + sp70.gain = var_s0->parentLayer->channel->reverbIndex; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012CEC.s") + sp6F = var_s0->parentLayer->channel->bookOffset & 7; + if ((var_s0->parentLayer->channel->seqPlayer->muted) && + (var_s0->parentLayer->channel->muteBehavior & 8)) { + sp70.freqMod = 0.0f; + sp70.velocity = 0.0f; + } + } + sp70.freqMod *= (var_s0->vibratoFreqMod * var_s0->portamentoFreqMod); + sp70.freqMod *= gAudioBufferParams.resampleRate; + sp70.velocity *= temp_fs0; + func_80011890(temp_s1, &sp70); + noteSub->bitField1.bookOffset = sp6F; + next:; + } + } +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012E28.s") +void func_80012438(SequenceLayer* layer, s32 arg1) { + Note* temp_v0; + NoteAttributes* temp_v0_3; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012E5C.s") + if (layer == NO_LAYER) { + return; + } + layer->unk_3 = 0; + if (layer->note == NULL) { + return; + } + temp_v0 = layer->note; + if (layer == temp_v0->playbackState.wantedParentLayer) { + temp_v0->playbackState.wantedParentLayer = NO_LAYER; + } -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012E88.s") + if (layer != temp_v0->playbackState.parentLayer) { + if ((temp_v0->playbackState.parentLayer == NO_LAYER) && + (temp_v0->playbackState.wantedParentLayer == NO_LAYER) && + (layer == temp_v0->playbackState.prevParentLayer) && (arg1 != 6)) { + temp_v0->playbackState.adsr.fadeOutVel = gAudioBufferParams.ticksPerUpdateInv; + temp_v0->playbackState.adsr.action.asByte |= 0x10; + } + return; + } + temp_v0_3 = &temp_v0->playbackState.attributes; + if (temp_v0->playbackState.adsr.state != 6) { + temp_v0_3->freqMod = layer->noteFreqMod; + temp_v0_3->velocity = layer->noteVelocity; + temp_v0_3->pan = layer->notePan; + temp_v0_3->stereo = layer->stereo; + if (layer->channel != NULL) { + temp_v0_3->reverb = layer->channel->targetReverbVol; + temp_v0_3->gain = layer->channel->reverbIndex; + if (layer->channel->seqPlayer->muted && (layer->channel->muteBehavior & 8)) { + temp_v0->noteSubEu.bitField0.finished = 1; + } + } + temp_v0->playbackState.priority = 1; + temp_v0->playbackState.prevParentLayer = temp_v0->playbackState.parentLayer; + temp_v0->playbackState.parentLayer = NO_LAYER; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012ED4.s") + if (arg1 == 7) { + temp_v0->playbackState.adsr.fadeOutVel = gAudioBufferParams.ticksPerUpdateInv; + temp_v0->playbackState.adsr.action.asByte |= 0x10; + temp_v0->playbackState.unk_04 = 2; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_80012F24.s") + } else { + temp_v0->playbackState.unk_04 = 1; + temp_v0->playbackState.adsr.action.asByte |= 0x20; + if (layer->adsr.decayIndex == 0) { + temp_v0->playbackState.adsr.fadeOutVel = + layer->channel->adsr.decayIndex * gAudioBufferParams.ticksPerUpdateInvScaled; + } else { + temp_v0->playbackState.adsr.fadeOutVel = + layer->adsr.decayIndex * gAudioBufferParams.ticksPerUpdateInvScaled; + } + temp_v0->playbackState.adsr.sustain = + (s32) layer->channel->adsr.sustain * temp_v0->playbackState.adsr.current * 0.00390625f; + } + } + if (arg1 == 6) { + func_80012C40(temp_v0); + func_80012C00(&temp_v0->listItem.pool->decaying, &temp_v0->listItem); + } +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_8001301C.s") +void func_8001266C(SequenceLayer* layer) { + func_80012438(layer, 6); +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_playback/func_800132E8.s") +void func_8001268C(SequenceLayer* layer) { + func_80012438(layer, 7); +} + +s32 func_800126AC(Note* note, SequenceLayer* layer, s32 arg2) { + f32 var_fv0; + u8 var_v1 = 0; + + if (arg2 < 128) { + arg2 = 128; + } + var_fv0 = layer->freqMod; + if ((layer->portamento.mode != 0) && (layer->portamento.extent > 0.0f)) { + var_fv0 *= layer->portamento.extent + 1.0f; + } + if (var_fv0 < 1.0f) { + var_fv0 = 1.0465f; + } else if (var_fv0 < 2.0f) { + var_v1 = 1; + var_fv0 = 0.52325f; + } else if (var_fv0 < 4.0f) { + var_v1 = 2; + var_fv0 = 0.26263f; + } else { + var_v1 = 3; + var_fv0 = 0.13081f; + } + + layer->freqMod *= var_fv0; + note->playbackState.waveId = arg2; + note->playbackState.harmonicIndex = var_v1; + note->noteSubEu.waveSampleAddr = &gWaveSamples[arg2 - 128][var_v1 * 64]; + return var_v1; +} + +void func_800127B0(Note* note, SequenceLayer* layer) { + s32 sp1C; + s32 var_a2; + + var_a2 = layer->instOrWave; + if (var_a2 == 0xFF) { + var_a2 = layer->channel->instOrWave; + } + sp1C = note->playbackState.harmonicIndex; + note->synthesisState.samplePosInt = + (note->synthesisState.samplePosInt * gSamplesPerWavePeriod[func_800126AC(note, layer, var_a2)]) / + gSamplesPerWavePeriod[sp1C]; +} + +void func_80012854(AudioListItem* item) { + item->prev = item; + item->next = item; + item->u.value = NULL; +} + +void func_80012864(NotePool* pool) { + func_80012854(&pool->disabled); + func_80012854(&pool->decaying); + func_80012854(&pool->releasing); + func_80012854(&pool->active); + pool->disabled.pool = pool; + pool->decaying.pool = pool; + pool->releasing.pool = pool; + pool->active.pool = pool; +} + +void func_800128B4(void) { + s32 var_s1; + + func_80012864(&gNoteFreeLists); + for (var_s1 = 0; var_s1 < gNumNotes; var_s1++) { + gNotes[var_s1].listItem.u.value = &gNotes[var_s1]; + gNotes[var_s1].listItem.prev = NULL; + func_800145BC(&gNoteFreeLists.disabled, &gNotes[var_s1]); + } +} + +void func_80012964(NotePool* pool) { + s32 var_s3; + AudioListItem* sp48; + AudioListItem* var_s0; + AudioListItem* sp40; + + for (var_s3 = 0; var_s3 < 4; var_s3++) { + switch (var_s3) { /* irregular */ + case 0: + sp48 = &pool->disabled; + sp40 = &gNoteFreeLists.disabled; + break; + case 1: + sp48 = &pool->decaying; + sp40 = &gNoteFreeLists.decaying; + break; + case 2: + sp48 = &pool->releasing; + sp40 = &gNoteFreeLists.releasing; + break; + case 3: + sp48 = &pool->active; + sp40 = &gNoteFreeLists.active; + break; + } + + while (true) { + var_s0 = sp48->next; + if ((var_s0 == sp48) || (var_s0 == NULL)) { + break; + } + func_80012C40((Note*) var_s0); + func_800145BC(sp40, var_s0); + } + } +} + +void func_80012AC4(NotePool* pool, s32 arg1) { + s32 var_s0; + s32 var_s4; + AudioListItem* temp_v0; + AudioListItem* sp48; + AudioListItem* sp44; + + func_80012964(pool); + var_s4 = 0; + var_s0 = 0; + while (var_s0 < arg1) { + if (var_s4 == 4) { + return; + } + switch (var_s4) { + case 0: + sp48 = &gNoteFreeLists.disabled; + sp44 = &pool->disabled; + break; + case 1: + sp48 = &gNoteFreeLists.decaying; + sp44 = &pool->decaying; + break; + case 2: + sp48 = &gNoteFreeLists.releasing; + sp44 = &pool->releasing; + break; + case 3: + sp48 = &gNoteFreeLists.active; + sp44 = &pool->active; + break; + } + while (var_s0 < arg1) { + temp_v0 = func_800145FC(sp48); + if (temp_v0 == NULL) { + break; + } + func_800145BC(sp44, temp_v0); + var_s0++; + } + var_s4++; + } +} + +void func_80012C00(AudioListItem* item1, AudioListItem* item2) { + if (item2->prev == NULL) { + item2->prev = item1; + item2->next = item1->next; + item1->next->prev = item2; + item1->next = item2; + item1->u.count += 1; + item2->pool = item1->pool; + } +} + +void func_80012C40(Note* note) { + if (note->listItem.prev != NULL) { + note->listItem.prev->next = note->listItem.next; + note->listItem.next->prev = note->listItem.prev; + note->listItem.prev = NULL; + } +} + +Note* func_80012C6C(AudioListItem* item, s32 arg1) { + AudioListItem* var_v0; + AudioListItem* var_v1; + void* temp_a0; + + var_v0 = item->next; + if (var_v0 == item) { + return NULL; + } + for (var_v1 = var_v0; var_v0 != item; var_v0 = var_v0->next) { + if (((Note*) var_v1->u.value)->playbackState.priority >= ((Note*) var_v0->u.value)->playbackState.priority) { + var_v1 = var_v0; + } + // var_v0 = var_v0->next; + } + if (var_v1 == NULL) { + return NULL; + } + + if (((Note*) var_v1->u.value)->playbackState.priority >= arg1) { + return NULL; + } + return (Note*) var_v1->u.value; +} + +void func_80012CEC(Note* note, SequenceLayer* layer) { + s32 pad[4]; + s32 var_a2; + NoteSubEu* temp_v0; + + note->playbackState.prevParentLayer = NO_LAYER; + note->playbackState.parentLayer = layer; + note->playbackState.priority = layer->channel->notePriority; + layer->ignoreDrumPan = 1; + layer->unk_3 = 3; + layer->note = note; + layer->channel->noteUnused = note; + layer->channel->layerUnused = layer; + layer->noteVelocity = 0.0f; + func_80011EB8(note); + var_a2 = layer->instOrWave; + temp_v0 = ¬e->noteSubEu; + if (var_a2 == 0xFF) { + var_a2 = layer->channel->instOrWave; + } + temp_v0->waveSampleAddr = (s16*) layer->tunedSample; + if (var_a2 >= 0x80) { + temp_v0->bitField1.isSyntheticWave = 1; + } else { + temp_v0->bitField1.isSyntheticWave = 0; + } + if (temp_v0->bitField1.isSyntheticWave) { + func_800126AC(note, layer, var_a2); + } + note->playbackState.fontId = layer->channel->fontId; + temp_v0->bitField0.stereoHeadsetEffects = layer->channel->stereoHeadsetEffects; + temp_v0->bitField1.reverbIndex = layer->channel->someOtherPriority & 3; +} + +void func_80012E28(Note* note, SequenceLayer* layer) { + func_8001268C(note->playbackState.parentLayer); + note->playbackState.wantedParentLayer = layer; +} + +void func_80012E5C(Note* note, SequenceLayer* layer) { + note->playbackState.wantedParentLayer = layer; + note->playbackState.priority = layer->channel->notePriority; + note->playbackState.adsr.fadeOutVel = gAudioBufferParams.ticksPerUpdateInv; + note->playbackState.adsr.action.asByte |= 0x10; +} + +Note* func_80012E88(NotePool* pool, SequenceLayer* layer) { + Note* temp_v0 = func_800145FC(&pool->disabled); + + if (temp_v0 != NULL) { + func_80012CEC(temp_v0, layer); + func_80012C00(&pool->active, &temp_v0->listItem); + } + return temp_v0; +} + +Note* func_80012ED4(NotePool* pool, SequenceLayer* layer) { + Note* sp1C = func_800145FC(&pool->decaying); + + if (sp1C != NULL) { + func_80012E5C(sp1C, layer); + func_800145BC(&pool->releasing, &sp1C->listItem); + } + return sp1C; +} + +Note* func_80012F24(NotePool* pool, SequenceLayer* layer) { + Note* sp34; + Note* sp30; + s32 sp2C; + s32 sp28; + + sp2C = sp28 = 0x10; + sp34 = func_80012C6C(&pool->releasing, layer->channel->notePriority); + if (sp34 != NULL) { + sp2C = sp34->playbackState.priority; + } + sp30 = func_80012C6C(&pool->active, layer->channel->notePriority); + if (sp30 != NULL) { + sp28 = sp30->playbackState.priority; + } + if ((sp34 == NULL) && (sp30 == NULL)) { + return NULL; + } + if (sp28 < sp2C) { + func_80012C40(sp30); + func_80012E28(sp30, layer); + func_800145BC(&pool->releasing, &sp30->listItem); + sp30->playbackState.priority = layer->channel->notePriority; + return sp30; + } else { + sp34->playbackState.wantedParentLayer = layer; + sp34->playbackState.priority = layer->channel->notePriority; + return sp34; + } +} + +Note* func_8001301C(SequenceLayer* layer) { + Note* sp24; + + if (layer->channel->noteAllocPolicy & 1) { + sp24 = layer->note; + if ((sp24 != NULL) && (layer == sp24->playbackState.prevParentLayer) && + (sp24->playbackState.wantedParentLayer == NO_LAYER)) { + + func_80012E5C(sp24, layer); + func_80012C40(sp24); + func_800145BC(&sp24->listItem.pool->releasing, &sp24->listItem); + return sp24; + } + } + + if (layer->channel->noteAllocPolicy & 2) { + if (((sp24 = func_80012E88(&layer->channel->notePool, layer)) != NULL) || + ((sp24 = func_80012ED4(&layer->channel->notePool, layer)) != NULL) || + ((sp24 = func_80012F24(&layer->channel->notePool, layer)) != NULL)) { + return sp24; + } + } else if (layer->channel->noteAllocPolicy & 4) { + if (((sp24 = func_80012E88(&layer->channel->notePool, layer)) != NULL) || + ((sp24 = func_80012E88(&layer->channel->seqPlayer->notePool, layer)) != NULL) || + ((sp24 = func_80012ED4(&layer->channel->notePool, layer)) != NULL) || + ((sp24 = func_80012ED4(&layer->channel->seqPlayer->notePool, layer)) != NULL) || + ((sp24 = func_80012F24(&layer->channel->notePool, layer)) != NULL) || + ((sp24 = func_80012F24(&layer->channel->seqPlayer->notePool, layer)) != NULL)) { + return sp24; + } + } else if (layer->channel->noteAllocPolicy & 8) { + if (((sp24 = func_80012E88(&gNoteFreeLists, layer)) != NULL) || + ((sp24 = func_80012ED4(&gNoteFreeLists, layer)) != NULL) || + ((sp24 = func_80012F24(&gNoteFreeLists, layer)) != NULL)) { + return sp24; + } + } else { + if (((sp24 = func_80012E88(&layer->channel->notePool, layer)) != NULL) || + ((sp24 = func_80012E88(&layer->channel->seqPlayer->notePool, layer)) != NULL) || + ((sp24 = func_80012E88(&gNoteFreeLists, layer)) != NULL) || + ((sp24 = func_80012ED4(&layer->channel->notePool, layer)) != NULL) || + ((sp24 = func_80012ED4(&layer->channel->seqPlayer->notePool, layer)) != NULL) || + ((sp24 = func_80012ED4(&gNoteFreeLists, layer)) != NULL) || + ((sp24 = func_80012F24(&layer->channel->notePool, layer)) != NULL) || + ((sp24 = func_80012F24(&layer->channel->seqPlayer->notePool, layer)) != NULL) || + ((sp24 = func_80012F24(&gNoteFreeLists, layer)) != NULL)) { + return sp24; + } + } + layer->unk_3 = 0; + return NULL; +} + +void func_800132E8(void) { + s32 i; + Note* note; + + for (i = 0; i < gNumNotes; i++) { + note = &gNotes[i]; + + note->noteSubEu = gZeroNoteSub; + + note->playbackState.priority = 0; + note->playbackState.unk_04 = 0; + note->playbackState.parentLayer = NO_LAYER; + note->playbackState.wantedParentLayer = NO_LAYER; + note->playbackState.prevParentLayer = NO_LAYER; + note->playbackState.waveId = 0; + note->playbackState.attributes.velocity = 0.0f; + note->playbackState.adsrVolModUnused = 0; + note->playbackState.adsr.state = 0; + note->playbackState.adsr.action.asByte = 0; + note->playbackState.vibratoState.active = 0; + note->playbackState.portamento.cur = 0.0f; + note->playbackState.portamento.speed = 0.0f; + + note->synthesisState.synthesisBuffers = AudioHeap_Alloc(&gMiscPool, sizeof(Note)); + } +} diff --git a/src/main/audio_seqplayer.c b/src/main/audio_seqplayer.c index 34dbf416..7cdb9db7 100644 --- a/src/main/audio_seqplayer.c +++ b/src/main/audio_seqplayer.c @@ -33,52 +33,350 @@ static char devstr28[] = "Macro Level Over Error!\n"; static char devstr29[] = "Group:Undefine upper C0h command (%x)\n"; static char devstr30[] = "Group:Undefined Command\n"; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_80013EA0.s") +void func_80013EA0(SequenceChannel* channel) { + s32 i; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_80013FC4.s") + channel->enabled = 0; + channel->finished = 0; + channel->stopScript = 0; + channel->muted = 0; + channel->hasInstrument = 0; + channel->stereoHeadsetEffects = 0; + channel->transposition = 0; + channel->largeNotes = 0; + channel->bookOffset = 0; + channel->changes.asByte = 0xFF; + channel->scriptState.depth = 0; + channel->newPan = 0x40; + channel->panChannelWeight = 0x80; + channel->noteUnused = NULL; + channel->someOtherPriority = 0; + channel->targetReverbVol = 0; + channel->reverbIndex = 0; + channel->notePriority = 3; + channel->delay = 0; + channel->adsr.envelope = gDefaultEnvelope; + channel->adsr.decayIndex = 0x20; + channel->vibratoRateTarget = 0x800; + channel->vibratoRateStart = 0x800; + channel->adsr.sustain = 0; + channel->vibratoDepthTarget = 0; + channel->vibratoDepthStart = 0; + channel->vibratoRateChangeDelay = 0; + channel->vibratoDepthChangeDelay = 0; + channel->vibratoDelay = 0; + channel->volume = 1.0f; + channel->volumeMod = 1.0f; + channel->freqMod = 1.0f; + for (i = 0; i < 8; i++) { + channel->seqScriptIO[i] = -1; + } + channel->unused = 0; + func_80012864(&channel->notePool); +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800140D0.s") +s32 func_80013FC4(SequenceChannel* channel, s32 arg1) { + SequenceLayer* temp_v0; + SequenceLayer* temp; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_8001410C.s") + if (channel->layers[arg1] == NULL) { + temp_v0 = func_800145FC(&gLayerFreeList); + channel->layers[arg1] = temp_v0; + if (temp_v0 == NULL) { + channel->layers[arg1] = NULL; + return -1; + } + } else { + func_8001266C(channel->layers[arg1]); + } + temp = channel->layers[arg1]; + temp->channel = channel; + temp->adsr = channel->adsr; + temp->enabled = 1; + temp->muted = 0; + temp->continuousNotes = 0; + temp->finished = 0; + temp->adsr.decayIndex = 0; + temp->bit1 = 0; + temp->stereo.asByte = 0x40; + temp->portamento.mode = 0; + temp->state.depth = 0; + temp->unk_3 = 0; + temp->gateTime = 0x80; + temp->pan = 0x40; + temp->transposition = 0; + temp->delay = 0; + temp->gateDelay = 0; + temp->delay2 = 0; + temp->note = NULL; + temp->instrument = NULL; + temp->instOrWave = 0xFF; + temp->freqMod = 1.0f; + temp->velocitySquare = 0.0f; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_8001415C.s") + return 0; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800141C8.s") +void func_800140D0(SequenceLayer* layer) { + if (layer != NULL) { + func_8001266C(layer); + layer->enabled = 0; + layer->finished = 1; + } +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_80014244.s") +void func_8001410C(SequenceChannel* channel, s32 arg1) { + SequenceLayer* temp_a2 = channel->layers[arg1]; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_80014370.s") + if (temp_a2 != NULL) { + func_800145BC(&gLayerFreeList, &temp_a2->listItem); + func_800140D0(temp_a2); + channel->layers[arg1] = NULL; + } +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_80014440.s") +void func_8001415C(SequenceChannel* channel) { + s32 var_s0; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800144E4.s") + for (var_s0 = 0; var_s0 < 4; var_s0++) { + func_8001410C(channel, var_s0); + } + func_80012964(&channel->notePool); + channel->enabled = 0; + channel->finished = 1; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800145BC.s") +SequenceChannel* func_800141C8(void) { + s32 i; + SequenceChannel* var_v1; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800145FC.s") + for (i = 0; i < 48; i++) { + if (gSeqChannels[i].seqPlayer == NULL) { + return &gSeqChannels[i]; + } + } + return &gSeqChannelNone; +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_8001463C.s") +void func_80014244(SequencePlayer* seqPlayer, u16 arg1) { + SequenceChannel* temp_s0; + SequenceChannel* temp_v0; + s32 i; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800146C0.s") + for (i = 0; i < 16; i++) { + if (arg1 & 1) { + temp_s0 = seqPlayer->channels[i]; + if ((((u32) temp_s0 != (u32) &gSeqChannelNone) == 1) && (seqPlayer == temp_s0->seqPlayer)) { + func_8001415C(temp_s0); + temp_s0->seqPlayer = NULL; + } + temp_v0 = func_800141C8(); + if (((u32) temp_v0 == (u32) &gSeqChannelNone) != 0) { + D_80155D88 = i + 0x10000; + seqPlayer->channels[i] = temp_v0; + } else { + func_80013EA0(temp_v0); + seqPlayer->channels[i] = temp_v0; + temp_v0->seqPlayer = seqPlayer; + temp_v0->fontId = seqPlayer->defaultFont; + temp_v0->muteBehavior = seqPlayer->muteBehavior; + temp_v0->noteAllocPolicy = seqPlayer->noteAllocPolicy; + } + } + arg1 = arg1 >> 1; + } +} -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800146D4.s") +void func_80014370(SequencePlayer* seqPlayer, u16 arg1) { + s32 i; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_80014704.s") + for (i = 0; i < 16; i++) { + if (arg1 & 1) { + SequenceChannel* temp_s0 = seqPlayer->channels[i]; + + if (((u32) temp_s0 != (u32) &gSeqChannelNone) == 1) { + if (seqPlayer == temp_s0->seqPlayer) { + func_8001415C(temp_s0); + if (0) {} + temp_s0->seqPlayer = NULL; + } + seqPlayer->channels[i] = &gSeqChannelNone; + } + } + arg1 = arg1 >> 1; + } +} + +void func_80014440(SequencePlayer* seqPlayer, u8 arg1, u8* arg2) { + SequenceChannel* temp_s2 = seqPlayer->channels[arg1]; + s32 i; + + if (((u32) temp_s2 != (u32) &gSeqChannelNone) != 0) { + temp_s2->scriptState.depth = 0; + temp_s2->scriptState.pc = arg2; + temp_s2->enabled = 1; + temp_s2->finished = 0; + temp_s2->delay = 0; + for (i = 0; i < 4; i++) { + if (temp_s2->layers[i] != NULL) { + func_8001410C(temp_s2, i); + } + } + } +} + +void func_800144E4(SequencePlayer* seqPlayer) { + func_80014370(seqPlayer, 0xFFFF); + func_80012964(&seqPlayer->notePool); + seqPlayer->finished = 1; + seqPlayer->enabled = 0; + if ((gSeqLoadStatus[seqPlayer->seqId] >= 2) && (gSeqLoadStatus[seqPlayer->seqId] != 5)) { + gSeqLoadStatus[seqPlayer->seqId] = 3; + } + if ((gFontLoadStatus[seqPlayer->defaultFont] >= 2) && (gFontLoadStatus[seqPlayer->defaultFont] != 5)) { + gFontLoadStatus[seqPlayer->defaultFont] = 4; + } + if (seqPlayer->defaultFont == gFontCache.temporary.entries[0].id) { + gFontCache.temporary.nextSide = 1; + } else if (seqPlayer->defaultFont == gFontCache.temporary.entries[1].id) { + gFontCache.temporary.nextSide = 0; + } +} + +void func_800145BC(AudioListItem* list, AudioListItem* item) { + if (item->prev == NULL) { + list->prev->next = item; + item->prev = list->prev; + item->next = list; + list->prev = item; + list->u.count++; + item->pool = list->pool; + } +} + +void* func_800145FC(AudioListItem* list) { + AudioListItem* item = list->prev; + + if (item == list) { + return NULL; + } + item->prev->next = list; + list->prev = item->prev; + item->prev = NULL; + list->u.count--; + return item->u.count; +} + +void func_8001463C(void) { + s32 i; + + gLayerFreeList.prev = &gLayerFreeList; + gLayerFreeList.next = &gLayerFreeList; + gLayerFreeList.u.value = NULL; + gLayerFreeList.pool = NULL; + + for (i = 0; i < 64; i++) { + gSeqLayers[i].listItem.u.value = &gSeqLayers[i]; + gSeqLayers[i].listItem.prev = NULL; + func_800145BC(&gLayerFreeList, &gSeqLayers[i].listItem); + } +} + +u8 func_800146C0(SeqScriptState* state) { + return *(state->pc++); +} + +s16 func_800146D4(SeqScriptState* state) { + s16 ret = *(state->pc++) << 8; + + ret = *(state->pc++) | ret; + return ret; +} + +u16 func_80014704(SeqScriptState* state) { + u16 ret = *(state->pc++); + + if (ret & 0x80) { + ret = (ret << 8) & 0x7F00; + ret = *(state->pc++) | ret; + } + return ret; +} #pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_80014748.s") -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800152C0.s") +u8 func_800152C0(SequenceChannel* channel, u8 arg1, Instrument** instrument, AdsrSettings* adsrSettings) { + Instrument* temp_v0; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_80015330.s") + temp_v0 = Audio_GetInstrument(channel->fontId, arg1); + if (temp_v0 == NULL) { + *instrument = NULL; + return 0; + } -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800153C4.s") + adsrSettings->envelope = temp_v0->envelope; + adsrSettings->decayIndex = temp_v0->adsrDecayIndex; + *instrument = temp_v0; + arg1++; + return arg1; +} + +void func_80015330(SequenceChannel* channel, u8 arg1) { + if (arg1 >= 0x80) { + channel->instOrWave = arg1; + channel->instrument = NULL; + } else if (arg1 == 0x7F) { + channel->instOrWave = 0; + channel->instrument = (Instrument*) 1; + } else { + if ((channel->instOrWave = func_800152C0(channel, arg1, &channel->instrument, &channel->adsr)) == 0) { + channel->hasInstrument = 0; + return; + } + } + channel->hasInstrument = 1; +} + +void func_800153C4(SequenceChannel* channel, u8 arg1) { + channel->volume = (s32) arg1 / 127.0f; +} #pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800153E8.s") #pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_80015FD4.s") -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_8001678C.s") +void func_8001678C(s32 arg0) { + s32 i; -#pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_80016804.s") + for (i = 0; i < 4; i++) { + if (gSeqPlayers[i].enabled == 1) { + func_80015FD4(&gSeqPlayers[i]); + func_800135A8(&gSeqPlayers[i]); + } + } + func_80011FA8(); +} + +void func_80016804(s32 arg0) { + SequencePlayer* seqPlayer = &gSeqPlayers[arg0]; + + func_800144E4(seqPlayer); + seqPlayer->delay = 0; + seqPlayer->state = 1; + seqPlayer->fadeTimer = 0; + seqPlayer->fadeTimerUnkEu = 0; + seqPlayer->tempoAcc = 0; + seqPlayer->tempo = 0x1680; + seqPlayer->tempoChange = 0; + seqPlayer->transposition = 0; + seqPlayer->noteAllocPolicy = 0; + seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable; + seqPlayer->shortNoteGateTimeTable = gDefaultShortNoteGateTimeTable; + seqPlayer->fadeVolume = 1.0f; + seqPlayer->fadeVolumeMod = 1.0f; + seqPlayer->fadeVelocity = 0.0f; + seqPlayer->volume = 0.0f; + seqPlayer->muteVolumeMod = 0.5f; +} #pragma GLOBAL_ASM("asm/us/nonmatchings/main/audio_seqplayer/func_800168BC.s") diff --git a/src/main/audio_synthesis.c b/src/main/audio_synthesis.c index c7e26773..4e95dcfa 100644 --- a/src/main/audio_synthesis.c +++ b/src/main/audio_synthesis.c @@ -1,8 +1,6 @@ #include "sys.h" #include "sf64audio_provisional.h" -extern s16 D_800DD200[]; - s32 D_80145D40; f32 D_80145D48[256]; f32 D_80146148[256]; diff --git a/src/main/fox_edisplay.c b/src/main/fox_edisplay.c index 314931a9..9f3e58ac 100644 --- a/src/main/fox_edisplay.c +++ b/src/main/fox_edisplay.c @@ -1,6 +1,6 @@ -// #include "prevent_bss_reordering.h" -#include "global.h" +#include "global.h" +#include "prevent_bss_reordering.h" Vec3f D_801615D0; Vec3f D_801615E0; s32 D_801615EC; diff --git a/src/main/note_data.c b/src/main/note_data.c index 74024b13..4c7c826f 100644 --- a/src/main/note_data.c +++ b/src/main/note_data.c @@ -1,90 +1,5 @@ -#include "global.h" - -#define MK_CMD(b0, b1, b2, b3) \ - ((((b0) &0xFF) << 0x18) | (((b1) &0xFF) << 0x10) | (((b2) &0xFF) << 0x8) | (((b3) &0xFF) << 0)) - -#define NO_LAYER ((SequenceLayer*) (-1)) - -#define TATUMS_PER_BEAT 48 - -#define IS_SEQUENCE_CHANNEL_VALID(ptr) ((u32) (ptr) != (u32) &gAudioCtx.sequenceChannelNone) -#define SEQ_NUM_CHANNELS 16 -#define SEQ_IO_VAL_NONE -1 - -#define MAX_CHANNELS_PER_BANK 3 - -#define MUTE_BEHAVIOR_3 (1 << 3) // prevent further NoteUnkStructs from playing -#define MUTE_BEHAVIOR_4 (1 << 4) // stop something in seqLayer scripts -#define MUTE_BEHAVIOR_SOFTEN (1 << 5) // lower volume, by default to half -#define MUTE_BEHAVIOR_STOP_NOTES (1 << 6) // prevent further notes from playing -#define MUTE_BEHAVIOR_STOP_SCRIPT (1 << 7) // stop processing sequence/channel scripts - -#define ADSR_DISABLE 0 -#define ADSR_HANG -1 -#define ADSR_GOTO -2 -#define ADSR_RESTART -3 - -// size of a single sample point -#define SAMPLE_SIZE sizeof(s16) - -// Samples are processed in groups of 16 called a "frame" -#define SAMPLES_PER_FRAME ADPCMFSIZE - -// The length of one left/right channel is 13 frames -#define DMEM_1CH_SIZE (13 * SAMPLES_PER_FRAME * SAMPLE_SIZE) -// Both left and right channels -#define DMEM_2CH_SIZE (2 * DMEM_1CH_SIZE) - -#define AIBUF_LEN (88 * SAMPLES_PER_FRAME) // number of samples -#define AIBUF_SIZE (AIBUF_LEN * SAMPLE_SIZE) // number of bytes - -// Filter sizes -#define FILTER_SIZE (8 * SAMPLE_SIZE) -#define FILTER_BUF_PART1 (8 * SAMPLE_SIZE) -#define FILTER_BUF_PART2 (8 * SAMPLE_SIZE) - -// Must be the same amount of samples as copied by aDuplicate() (audio microcode) -#define WAVE_SAMPLE_COUNT 64 - -#define AUDIO_RELOCATED_ADDRESS_START K0BASE - -typedef struct { - /* 0x0 */ s16 delay; - /* 0x2 */ s16 arg; -} EnvelopePoint; // size = 0x4 - -typedef struct { - /* 0x00 */ u32 start; - /* 0x04 */ u32 end; - /* 0x08 */ u32 count; - /* 0x0C */ char unk_0C[0x4]; - /* 0x10 */ s16 predictorState[16]; // only exists if count != 0. 8-byte aligned -} AdpcmLoop; // size = 0x30 (or 0x10) - -typedef struct { - /* 0x00 */ s32 order; - /* 0x04 */ s32 numPredictors; - /* 0x08 */ s16 book[1]; // size 8 * order * numPredictors. 8-byte aligned -} AdpcmBook; // size >= 0x8 - -typedef struct { - /* 0x00 */ u32 codec : 4; // The state of compression or decompression - /* 0x00 */ u32 medium : 2; // Medium where sample is currently stored - /* 0x00 */ u32 unk_bit26 : 1; - /* 0x00 */ u32 isRelocated : 1; // Has the sample header been relocated (offsets to pointers) - /* 0x01 */ u32 size : 24; // Size of the sample - /* 0x04 */ u8* sampleAddr; // Raw sample data. Offset from the start of the sample bank or absolute address to - // either rom or ram - /* 0x08 */ AdpcmLoop* - loop; // Adpcm loop parameters used by the sample. Offset from the start of the sound font / pointer to ram - /* 0x0C */ AdpcmBook* - book; // Adpcm book parameters used by the sample. Offset from the start of the sound font / pointer to ram -} Sample; // size = 0x10 - -typedef struct { - /* 0x00 */ Sample* sample; - /* 0x04 */ f32 tuning; // frequency scale factor -} TunedSample; // size = 0x8 +#include "sys.h" +#include "sf64audio_provisional.h" typedef struct { struct { @@ -310,12 +225,12 @@ EnvelopePoint gDefaultEnvelope[] = { { ADSR_DISABLE, 0 }, }; -NoteUnkStruct gZeroNoteSub = { 0 }; +NoteSubEu gZeroNoteSub = { 0 }; -NoteUnkStruct gDefaultNoteSub = { +NoteSubEu gDefaultNoteSub = { { 1, 1, 0, 0, 0, 0, 0, 0 }, { 0 }, - { 0 }, + 0, }; u16 gHaasEffectDelaySizes[64] = { diff --git a/src/overlays/ovl_menu/fox_map.c b/src/overlays/ovl_menu/fox_map.c index 13133b2f..77acfb1d 100644 --- a/src/overlays/ovl_menu/fox_map.c +++ b/src/overlays/ovl_menu/fox_map.c @@ -5,12 +5,11 @@ */ #include "mods.h" -#include "prevent_bss_reordering.h" -// #include "prevent_bss_reordering2.h" #include "global.h" #include "fox_map.h" #include "fox_option.h" - +#include "prevent_bss_reordering.h" +#include "prevent_bss_reordering2.h" // BSS STARTS HERE u8 D_menu_801B9410[96 * 96];