From e77a22e8a905f241d7b58889bcf4b12fb81dcf27 Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Thu, 24 Mar 2022 14:40:31 +1100 Subject: [PATCH] Audio_Heap OK and Documented (#621) * copy audio_heap progress from main branch * Add filter bugs * PR Review + Docs * format * typo * Improve audio buffer notes * Add documentation * PR Feedback * PR Suggestions * Fix bss * PR Suggestions * PR typo * Fix warning --- include/functions.h | 56 +- include/variables.h | 20 +- src/code/audio/audio_heap.c | 1686 +++++++++++++++++++++++++++- src/code/audio/audio_init_params.c | 2 +- src/code/audio/audio_seqplayer.c | 6 +- tools/disasm/functions.txt | 80 +- tools/disasm/variables.txt | 2 +- tools/sizes/code_functions.csv | 84 +- 8 files changed, 1735 insertions(+), 201 deletions(-) diff --git a/include/functions.h b/include/functions.h index 4dccf9a5b1..125517df23 100644 --- a/include/functions.h +++ b/include/functions.h @@ -3301,57 +3301,25 @@ s32 osFlashReadArray(OSIoMesg* mb, s32 priority, u32 pageNum, void* dramAddr, u3 // void func_8018A808(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE4 param_6); // void func_8018ACC4(void); // void func_8018AE34(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); -// void func_8018B0F0(void); -// void func_8018B10C(void); -// void func_8018B250(void); void AudioHeap_DiscardFont(s32 fontId); -// void func_8018B474(void); -void* AudioHeap_WritebackDCache(void* mem, size_t size); -// void func_8018B520(void); +void* AudioHeap_WritebackDCache(void* addr, size_t size); void* AudioHeap_AllocAttemptExternal(AudioAllocPool* pool, size_t size); -void* AudioHeap_AllocDmaMemory(AudioAllocPool* pool, u32 size); -// void func_8018B608(void); +void* AudioHeap_AllocDmaMemory(AudioAllocPool* pool, size_t size); void* AudioHeap_AllocZeroed(AudioAllocPool* pool, size_t size); -// void func_8018B69C(void); void* AudioHeap_Alloc(AudioAllocPool* pool, size_t size); -void AudioHeap_AllocPoolInit(AudioAllocPool* pool, void* mem, size_t size); -// void func_8018B768(void); -// void func_8018B77C(void); -// void func_8018B7BC(void); -void AudioHeap_InitMainPool(s32 initPoolSize); -// void func_8018B95C(void); -// void func_8018B9E0(void); -// void func_8018BA64(void); -// void func_8018BB28(void); +void AudioHeap_AllocPoolInit(AudioAllocPool* pool, void* addr, size_t size); +void AudioHeap_PopCache(s32 tableType); +void AudioHeap_InitMainPool(size_t initPoolSize); void* AudioHeap_AllocCached(s32 tableType, size_t size, s32 cache, s32 id); void* AudioHeap_SearchCaches(s32 tableType, s32 cache, s32 id); -// void func_8018C3D8(void); -// void func_8018C8E8(void); -// void func_8018C93C(void); -// void func_8018C994(void); -// void func_8018CB70(void); -// void func_8018CB78(void); -// void func_8018CC3C(void); +void AudioHeap_LoadFilter(s16* filter, s32 lowPassCutoff, s32 highPassCutoff); s32 AudioHeap_ResetStep(void); -// void func_8018CFAC(void); +void AudioHeap_Init(void); void* AudioHeap_SearchPermanentCache(s32 tableType, s32 id); void* AudioHeap_AllocPermanent(s32 tableType, s32 id, size_t size); -void* AudioHeap_AllocSampleCache(size_t size, s32 fontId, void* sampleAddr, s8 medium, s32 cache); -// void func_8018D6C8(void); -// void func_8018D760(void); -// void func_8018DA50(void); -// void func_8018DBC4(void); -// void func_8018DCB4(void); -// void func_8018DCF8(void); -// void func_8018DD98(void); -// void func_8018DDD4(void); -// void func_8018DF24(void); -// void func_8018DFE0(void); +void* AudioHeap_AllocSampleCache(size_t size, s32 sampleBankId, void* sampleAddr, s8 medium, s32 cache); void AudioHeap_ApplySampleBankCache(s32 sampleBankId); -// void func_8018E03C(void); -// void func_8018E2A8(void); -// void func_8018E344(void); -// void func_8018E8C8(void); +void AudioHeap_SetReverbData(s32 reverbIndex, u32 dataType, s32 data, s32 flags); void AudioLoad_DecreaseSampleDmaTtls(void); void* AudioLoad_DmaSampleData(uintptr_t devAddr, size_t size, s32 arg2, u8* dmaIndexRef, s32 medium); void AudioLoad_InitSampleDmaBuffers(s32 numNotes); @@ -3453,7 +3421,7 @@ void AudioSeq_SequenceChannelDisable(SequenceChannel* channel); // void func_80197B14(void); // void func_80197C0C(void); // void func_80197C8C(void); -// void func_80197D24(void); +void AudioSeq_SequencePlayerDisableAsFinished(SequencePlayer* seqPlayer); void AudioSeq_SequencePlayerDisable(SequencePlayer* seqPlayer); void AudioSeq_AudioListPushBack(AudioListItem* list, AudioListItem* item); void* AudioSeq_AudioListPopBack(AudioListItem* list); @@ -3476,9 +3444,9 @@ void func_80199268(s32* param_1); // void func_8019AA3C(void); // void func_8019AAF0(void); void AudioSeq_ResetSequencePlayer(SequencePlayer* seqPlayer); -// void func_8019AC10(void); +void AudioSeq_InitSequencePlayerChannels(s32 playerIdx); // void func_8019ACEC(void); -// void func_8019ADBC(void); +void AudioSeq_InitSequencePlayers(void); void func_8019AE40(s32 param_1, s32 param_2, u32 param_3, s32 param_4); void func_8019AEC0(UNK_PTR param_1, UNK_PTR param_2); // void func_8019AF00(void); diff --git a/include/variables.h b/include/variables.h index 1f198a15b6..1f0c54e3a9 100644 --- a/include/variables.h +++ b/include/variables.h @@ -1617,18 +1617,10 @@ extern Vec3s gZeroVec3s; extern Mtx gIdentityMtx; extern MtxF gIdentityMtxF; // extern UNK_TYPE1 D_801D1E70; -// extern UNK_TYPE1 gLowPassFilterData; -// extern UNK_TYPE1 gHighPassFilterData; -// extern UNK_TYPE1 gBandStopFilterData; -// extern UNK_TYPE1 gBandPassFilterData; -// extern UNK_TYPE1 gSawtoothWaveSample; -// extern UNK_TYPE1 gTriangleWaveSample; -// extern UNK_TYPE1 gSineWaveSample; -// extern UNK_TYPE1 gSquareWaveSample; -// extern UNK_TYPE1 gWhiteNoiseSample; -// extern UNK_TYPE1 D_801D4790; -// extern UNK_TYPE1 gEighthPulseWaveSample; -// extern UNK_TYPE1 gQuarterPulseWaveSample; +extern s16 gLowPassFilterData[]; +extern s16 gHighPassFilterData[]; +extern s16 gBandStopFilterData[]; +extern s16 gBandPassFilterData[]; extern s16* gWaveSamples[9]; extern UNK_PTR D_801D4D98; extern UNK_PTR D_801D4DB0; @@ -1837,7 +1829,7 @@ extern s8 D_801DB4B8; // extern UNK_TYPE1 D_801DB8B8; // extern UNK_TYPE1 D_801DB900; extern UNK_PTR D_801DB930; -extern AudioSpec D_801DB958[21]; +extern AudioSpec gAudioSpecs[21]; // rodata extern f32 D_801DBDF0; @@ -3466,7 +3458,7 @@ extern StackEntry sys_flashromStackEntry; extern OSThread sys_flashromOSThread; extern s80185D40 D_801FD008; extern OSMesg D_801FD034; -// extern UNK_TYPE1 D_801FD120; +extern s32 D_801FD120; // extern UNK_TYPE1 D_801FD140; // extern UNK_TYPE1 D_801FD158; // extern UNK_TYPE1 D_801FD198; diff --git a/src/code/audio/audio_heap.c b/src/code/audio/audio_heap.c index 70c7379304..b06f6a5776 100644 --- a/src/code/audio/audio_heap.c +++ b/src/code/audio/audio_heap.c @@ -1,111 +1,1687 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B0F0.s") +void* AudioHeap_SearchRegularCaches(s32 tableType, s32 cache, s32 id); +void AudioHeap_InitSampleCaches(size_t persistentSampleCacheSize, size_t temporarySampleCacheSize); +SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(size_t size); +void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry); +void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, SoundFontSample* sample); +SampleCacheEntry* AudioHeap_AllocPersistentSampleCacheEntry(size_t size); +void AudioHeap_DiscardSampleCaches(void); +void AudioHeap_DiscardSampleBank(s32 sampleBankId); +void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId); +void AudioHeap_DiscardSampleBanks(void); +void AudioHeap_InitReverb(s32 reverbIndex, ReverbSettings* settings, s32 flags); -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B10C.s") +#define gTatumsPerBeat (gAudioTatumInit[1]) -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B250.s") +f32 func_8018B0F0(f32 arg0) { + return 256.0f * gAudioContext.audioBufferParameters.unkUpdatesPerFrameScaled / arg0; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_DiscardFont.s") +void func_8018B10C(void) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B3FC.s") + gAudioContext.unk_3520[255] = func_8018B0F0(0.25f); + gAudioContext.unk_3520[254] = func_8018B0F0(0.33f); + gAudioContext.unk_3520[253] = func_8018B0F0(0.5f); + gAudioContext.unk_3520[252] = func_8018B0F0(0.66f); + gAudioContext.unk_3520[251] = func_8018B0F0(0.75f); -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B474.s") + for (i = 128; i < 251; i++) { + gAudioContext.unk_3520[i] = func_8018B0F0(251 - i); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_WritebackDCache.s") + for (i = 16; i < 128; i++) { + gAudioContext.unk_3520[i] = func_8018B0F0(4 * (143 - i)); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B520.s") + for (i = 1; i < 16; i++) { + gAudioContext.unk_3520[i] = func_8018B0F0(60 * (23 - i)); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_AllocAttemptExternal.s") + gAudioContext.unk_3520[0] = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_AllocDmaMemory.s") +void AudioHeap_ResetLoadStatus(void) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B608.s") + for (i = 0; i < ARRAY_COUNT(gAudioContext.fontLoadStatus); i++) { + if (gAudioContext.fontLoadStatus[i] != LOAD_STATUS_5) { + gAudioContext.fontLoadStatus[i] = LOAD_STATUS_0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_AllocZeroed.s") + for (i = 0; i < ARRAY_COUNT(gAudioContext.sampleFontLoadStatus); i++) { + if (gAudioContext.sampleFontLoadStatus[i] != LOAD_STATUS_5) { + gAudioContext.sampleFontLoadStatus[i] = LOAD_STATUS_0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B69C.s") + for (i = 0; i < ARRAY_COUNT(gAudioContext.seqLoadStatus); i++) { + if (gAudioContext.seqLoadStatus[i] != LOAD_STATUS_5) { + gAudioContext.seqLoadStatus[i] = LOAD_STATUS_0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_Alloc.s") +void AudioHeap_DiscardFont(s32 fontId) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_AllocPoolInit.s") + for (i = 0; i < gAudioContext.numNotes; i++) { + Note* note = &gAudioContext.notes[i]; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B768.s") + if (note->playbackState.fontId == fontId) { + if ((note->playbackState.unk_04 == 0) && (note->playbackState.priority != 0)) { + note->playbackState.parentLayer->enabled = false; + note->playbackState.parentLayer->finished = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B77C.s") + AudioPlayback_NoteDisable(note); + AudioPlayback_AudioListRemove(¬e->listItem); + AudioSeq_AudioListPushBack(&gAudioContext.noteFreeLists.disabled, ¬e->listItem); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B7AC.s") +void AudioHeap_ReleaseNotesForFont(s32 fontId) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B7BC.s") + for (i = 0; i < gAudioContext.numNotes; i++) { + Note* note = &gAudioContext.notes[i]; + NotePlaybackState* playbackState = ¬e->playbackState; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_InitMainPool.s") + if (playbackState->fontId == fontId) { + if (playbackState->priority != 0) { + playbackState->priority = 1; + playbackState->adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv; + playbackState->adsr.action.s.release = true; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B95C.s") +void AudioHeap_DiscardSequence(s32 seqId) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B9E0.s") + for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) { + if (gAudioContext.seqPlayers[i].enabled && gAudioContext.seqPlayers[i].seqId == seqId) { + AudioSeq_SequencePlayerDisable(&gAudioContext.seqPlayers[i]); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018BA64.s") +/** + * Perform a writeback from the L1 data cache to the ram. + */ +void* AudioHeap_WritebackDCache(void* addr, size_t size) { + Audio_WritebackDCache(addr, size); + if (addr) {} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018BB28.s") + // KSEG0 to KSEG1 (ensures data is written straight to ram instead of the data cache) + return OS_PHYSICAL_TO_K1(OS_K0_TO_PHYSICAL(addr)); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_AllocCached.s") +/** + * Attempt to allocated space on an external device. If no external device is available, + * then allocate space on the pool provided in the argument. + * Afterwards, zero all data pool the new allocated space + */ +void* AudioHeap_AllocZeroedAttemptExternal(AudioAllocPool* pool, size_t size) { + void* addr = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_SearchCaches.s") + if (gAudioContext.externalPool.startAddr != NULL) { + addr = AudioHeap_AllocZeroed(&gAudioContext.externalPool, size); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C3D8.s") + if (addr == NULL) { + addr = AudioHeap_AllocZeroed(pool, size); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C4E4.s") + return addr; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C8B8.s") +/** + * Attempt to allocated space on an external device. If no external device is available, + * then allocate space on the pool provided in the argument + */ +void* AudioHeap_AllocAttemptExternal(AudioAllocPool* pool, size_t size) { + void* addr = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C8E8.s") + if (gAudioContext.externalPool.startAddr != NULL) { + addr = AudioHeap_Alloc(&gAudioContext.externalPool, size); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C93C.s") + if (addr == NULL) { + addr = AudioHeap_Alloc(pool, size); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C994.s") + return addr; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018CB70.s") +void* AudioHeap_AllocDmaMemory(AudioAllocPool* pool, size_t size) { + void* addr = AudioHeap_Alloc(pool, size); -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018CB78.s") + if (addr != NULL) { + addr = AudioHeap_WritebackDCache(addr, size); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018CC3C.s") + return addr; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_ResetStep.s") +void* AudioHeap_AllocDmaMemoryZeroed(AudioAllocPool* pool, size_t size) { + void* addr = AudioHeap_AllocZeroed(pool, size); -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018CFAC.s") + if (addr != NULL) { + addr = AudioHeap_WritebackDCache(addr, size); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_SearchPermanentCache.s") + return addr; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_AllocPermanent.s") +/** + * Allocates space on a pool contained withing the heap and sets all the allocated space to 0 + */ +void* AudioHeap_AllocZeroed(AudioAllocPool* pool, size_t size) { + u8* addr = AudioHeap_Alloc(pool, size); + u8* ptr; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_AllocSampleCache.s") + if (addr != NULL) { + for (ptr = addr; ptr < pool->curAddr; ptr++) { + *ptr = 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018D6C8.s") + return addr; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018D760.s") +/** + * Tests the pool to see if the requested allocation would fit without actually allocating space. + * Returns NULL if there is not enough space on the pool. + * Else, return the address that would have been allocated + */ +void* AudioHeap_TestAlloc(AudioAllocPool* pool, size_t size) { + u8* oldAddr = pool->curAddr; + void* addr = AudioHeap_Alloc(pool, size); -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DA50.s") + // remove allocation from pool + if (addr != NULL) { + pool->curAddr = oldAddr; + pool->count--; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DBC4.s") + return addr; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DCB4.s") +/** + * Allocates space on the pool contained withing the heap. If there is not enough space on the pool, return NULL + */ +void* AudioHeap_Alloc(AudioAllocPool* pool, size_t size) { + size_t alignedSize = ALIGN16(size); + u8* curAddr = pool->curAddr; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DCF8.s") + if ((pool->startAddr + pool->size) >= (pool->curAddr + alignedSize)) { + pool->curAddr += alignedSize; + } else { + return NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DD98.s") + pool->count++; + return curAddr; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DDD4.s") +/** + * Initialize a pool at the requested address with the requested size. + * Store the metadata of this pool in AudioAllocPool* pool + */ +void AudioHeap_AllocPoolInit(AudioAllocPool* pool, void* addr, size_t size) { + pool->curAddr = pool->startAddr = (u8*)ALIGN16((uintptr_t)addr); + pool->size = size - ((uintptr_t)addr & 0xF); + pool->count = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DF24.s") +void AudioHeap_ClearPersistentCache(AudioPersistentCache* persistent) { + persistent->pool.count = 0; + persistent->numEntries = 0; + persistent->pool.curAddr = persistent->pool.startAddr; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DFE0.s") +void AudioHeap_ClearTemporaryCache(AudioTemporaryCache* temporary) { + temporary->pool.count = 0; + temporary->pool.curAddr = temporary->pool.startAddr; + temporary->nextSide = 0; + temporary->entries[0].addr = temporary->pool.startAddr; + temporary->entries[1].addr = temporary->pool.startAddr + temporary->pool.size; + temporary->entries[0].id = -1; + temporary->entries[1].id = -1; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/AudioHeap_ApplySampleBankCache.s") +void AudioHeap_ResetPool(AudioAllocPool* pool) { + pool->count = 0; + pool->curAddr = pool->startAddr; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018E03C.s") +void AudioHeap_PopCache(s32 tableType) { + AudioCache* loadedCache; + AudioAllocPool* persistentHeap; + AudioPersistentCache* persistent; + void* entryAddr; + u8* loadStatus; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018E2A8.s") + switch (tableType) { + case SEQUENCE_TABLE: + loadedCache = &gAudioContext.seqCache; + loadStatus = gAudioContext.seqLoadStatus; + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018E344.s") + case FONT_TABLE: + loadedCache = &gAudioContext.fontCache; + loadStatus = gAudioContext.fontLoadStatus; + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018E8C8.s") + case SAMPLE_TABLE: + loadedCache = &gAudioContext.sampleBankCache; + loadStatus = gAudioContext.sampleFontLoadStatus; + break; + } + + persistent = &loadedCache->persistent; + persistentHeap = &persistent->pool; + + if (persistent->numEntries == 0) { + return; + } + + entryAddr = persistent->entries[persistent->numEntries - 1].addr; + persistentHeap->curAddr = entryAddr; + persistentHeap->count--; + + if (tableType == SAMPLE_TABLE) { + AudioHeap_DiscardSampleBank(persistent->entries[persistent->numEntries - 1].id); + } + if (tableType == FONT_TABLE) { + AudioHeap_DiscardFont(persistent->entries[persistent->numEntries - 1].id); + } + + loadStatus[persistent->entries[persistent->numEntries - 1].id] = LOAD_STATUS_0; + persistent->numEntries--; +} + +void AudioHeap_InitMainPool(size_t mainPoolSplitSize) { + AudioHeap_AllocPoolInit(&gAudioContext.audioInitPool, gAudioContext.audioHeap, mainPoolSplitSize); + AudioHeap_AllocPoolInit(&gAudioContext.audioSessionPool, gAudioContext.audioHeap + mainPoolSplitSize, + gAudioContext.audioHeapSize - mainPoolSplitSize); + + gAudioContext.externalPool.startAddr = NULL; +} + +void AudioHeap_InitSessionPool(AudioSessionPoolSplit* split) { + gAudioContext.audioSessionPool.curAddr = gAudioContext.audioSessionPool.startAddr; + + AudioHeap_AllocPoolInit(&gAudioContext.miscPool, + AudioHeap_Alloc(&gAudioContext.audioSessionPool, split->miscPoolSize), split->miscPoolSize); + AudioHeap_AllocPoolInit(&gAudioContext.cachePool, + AudioHeap_Alloc(&gAudioContext.audioSessionPool, split->cachePoolSize), + split->cachePoolSize); +} + +void AudioHeap_InitCachePool(AudioCachePoolSplit* split) { + gAudioContext.cachePool.curAddr = gAudioContext.cachePool.startAddr; + + AudioHeap_AllocPoolInit(&gAudioContext.persistentCommonPool, + AudioHeap_Alloc(&gAudioContext.cachePool, split->persistentCommonPoolSize), + split->persistentCommonPoolSize); + AudioHeap_AllocPoolInit(&gAudioContext.temporaryCommonPool, + AudioHeap_Alloc(&gAudioContext.cachePool, split->temporaryCommonPoolSize), + split->temporaryCommonPoolSize); +} + +void AudioHeap_InitPersistentCache(AudioCommonPoolSplit* split) { + gAudioContext.persistentCommonPool.curAddr = gAudioContext.persistentCommonPool.startAddr; + + AudioHeap_AllocPoolInit(&gAudioContext.seqCache.persistent.pool, + AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->seqCacheSize), + split->seqCacheSize); + AudioHeap_AllocPoolInit(&gAudioContext.fontCache.persistent.pool, + AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->fontCacheSize), + split->fontCacheSize); + AudioHeap_AllocPoolInit(&gAudioContext.sampleBankCache.persistent.pool, + AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->sampleBankCacheSize), + split->sampleBankCacheSize); + + AudioHeap_ClearPersistentCache(&gAudioContext.seqCache.persistent); + AudioHeap_ClearPersistentCache(&gAudioContext.fontCache.persistent); + AudioHeap_ClearPersistentCache(&gAudioContext.sampleBankCache.persistent); +} + +void AudioHeap_InitTemporaryCache(AudioCommonPoolSplit* split) { + gAudioContext.temporaryCommonPool.curAddr = gAudioContext.temporaryCommonPool.startAddr; + + AudioHeap_AllocPoolInit(&gAudioContext.seqCache.temporary.pool, + AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->seqCacheSize), + split->seqCacheSize); + AudioHeap_AllocPoolInit(&gAudioContext.fontCache.temporary.pool, + AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->fontCacheSize), + split->fontCacheSize); + AudioHeap_AllocPoolInit(&gAudioContext.sampleBankCache.temporary.pool, + AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->sampleBankCacheSize), + split->sampleBankCacheSize); + + AudioHeap_ClearTemporaryCache(&gAudioContext.seqCache.temporary); + AudioHeap_ClearTemporaryCache(&gAudioContext.fontCache.temporary); + AudioHeap_ClearTemporaryCache(&gAudioContext.sampleBankCache.temporary); +} + +void* AudioHeap_AllocCached(s32 tableType, size_t size, s32 cache, s32 id) { + AudioCache* loadedCache; + AudioTemporaryCache* temporaryCache; + AudioAllocPool* temporaryPool; + void* persistentAddr; + void* temporaryAddr; + u8 loadStatusEntry0; + u8 loadStatusEntry1; + s32 i; + u8* loadStatus; + s32 side; + + switch (tableType) { + case SEQUENCE_TABLE: + loadedCache = &gAudioContext.seqCache; + loadStatus = gAudioContext.seqLoadStatus; + break; + + case FONT_TABLE: + loadedCache = &gAudioContext.fontCache; + loadStatus = gAudioContext.fontLoadStatus; + break; + + case SAMPLE_TABLE: + loadedCache = &gAudioContext.sampleBankCache; + loadStatus = gAudioContext.sampleFontLoadStatus; + break; + } + + if (cache == CACHE_TEMPORARY) { + temporaryCache = &loadedCache->temporary; + temporaryPool = &temporaryCache->pool; + + if ((s32)temporaryPool->size < (s32)size) { + return NULL; + } + + loadStatusEntry0 = + (temporaryCache->entries[0].id == -1) ? LOAD_STATUS_0 : loadStatus[temporaryCache->entries[0].id]; + loadStatusEntry1 = + (temporaryCache->entries[1].id == -1) ? LOAD_STATUS_0 : loadStatus[temporaryCache->entries[1].id]; + + if (tableType == FONT_TABLE) { + if (loadStatusEntry0 == LOAD_STATUS_4) { + for (i = 0; i < gAudioContext.numNotes; i++) { + if ((gAudioContext.notes[i].playbackState.fontId == temporaryCache->entries[0].id) && + gAudioContext.notes[i].noteSubEu.bitField0.enabled) { + break; + } + } + + if (i == gAudioContext.numNotes) { + AudioLoad_SetFontLoadStatus(temporaryCache->entries[0].id, LOAD_STATUS_3); + loadStatusEntry0 = LOAD_STATUS_3; + } + } + + if (loadStatusEntry1 == LOAD_STATUS_4) { + for (i = 0; i < gAudioContext.numNotes; i++) { + if ((gAudioContext.notes[i].playbackState.fontId == temporaryCache->entries[1].id) && + gAudioContext.notes[i].noteSubEu.bitField0.enabled) { + break; + } + } + + if (i == gAudioContext.numNotes) { + AudioLoad_SetFontLoadStatus(temporaryCache->entries[1].id, LOAD_STATUS_3); + loadStatusEntry1 = LOAD_STATUS_3; + } + } + } + + if (loadStatusEntry0 == LOAD_STATUS_0) { + temporaryCache->nextSide = 0; + } else if (loadStatusEntry1 == LOAD_STATUS_0) { + temporaryCache->nextSide = 1; + } else if ((loadStatusEntry0 == LOAD_STATUS_3) && (loadStatusEntry1 == LOAD_STATUS_3)) { + // Use the opposite side from last time. + } else if (loadStatusEntry0 == LOAD_STATUS_3) { + temporaryCache->nextSide = 0; + } else if (loadStatusEntry1 == LOAD_STATUS_3) { + temporaryCache->nextSide = 1; + } else { + // Check if there is a side which isn't in active use, if so, evict that one. + if (tableType == SEQUENCE_TABLE) { + if (loadStatusEntry0 == LOAD_STATUS_2) { + for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) { + if (gAudioContext.seqPlayers[i].enabled && + gAudioContext.seqPlayers[i].seqId == temporaryCache->entries[0].id) { + break; + } + } + + if (i == gAudioContext.audioBufferParameters.numSequencePlayers) { + temporaryCache->nextSide = 0; + goto done; + } + } + + if (loadStatusEntry1 == LOAD_STATUS_2) { + for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) { + if (gAudioContext.seqPlayers[i].enabled && + gAudioContext.seqPlayers[i].seqId == temporaryCache->entries[1].id) { + break; + } + } + + if (i == gAudioContext.audioBufferParameters.numSequencePlayers) { + temporaryCache->nextSide = 1; + goto done; + } + } + } else if (tableType == FONT_TABLE) { + if (loadStatusEntry0 == LOAD_STATUS_2) { + for (i = 0; i < gAudioContext.numNotes; i++) { + if ((gAudioContext.notes[i].playbackState.fontId == temporaryCache->entries[0].id) && + gAudioContext.notes[i].noteSubEu.bitField0.enabled) { + break; + } + } + if (i == gAudioContext.numNotes) { + temporaryCache->nextSide = 0; + goto done; + } + } + + if (loadStatusEntry1 == LOAD_STATUS_2) { + for (i = 0; i < gAudioContext.numNotes; i++) { + if ((gAudioContext.notes[i].playbackState.fontId == temporaryCache->entries[1].id) && + gAudioContext.notes[i].noteSubEu.bitField0.enabled) { + break; + } + } + if (i == gAudioContext.numNotes) { + temporaryCache->nextSide = 1; + goto done; + } + } + } + + // No such luck. Evict the side that wasn't chosen last time, except + // if it is being loaded into. + if (temporaryCache->nextSide == 0) { + if (loadStatusEntry0 == LOAD_STATUS_1) { + if (loadStatusEntry1 == LOAD_STATUS_1) { + goto fail; + } + temporaryCache->nextSide = 1; + } + } else { + if (loadStatusEntry1 == LOAD_STATUS_1) { + if (loadStatusEntry0 == LOAD_STATUS_1) { + goto fail; + } + temporaryCache->nextSide = 0; + } + } + + if (0) { + fail: + // Both sides are being loaded into. + return NULL; + } + } + done: + + side = temporaryCache->nextSide; + + if (temporaryCache->entries[side].id != -1) { + if (tableType == SAMPLE_TABLE) { + AudioHeap_DiscardSampleBank(temporaryCache->entries[side].id); + } + + loadStatus[temporaryCache->entries[side].id] = LOAD_STATUS_0; + + if (tableType == FONT_TABLE) { + AudioHeap_DiscardFont(temporaryCache->entries[side].id); + } + } + + switch (side) { + case 0: + temporaryCache->entries[0].addr = temporaryPool->startAddr; + temporaryCache->entries[0].id = id; + temporaryCache->entries[0].size = size; + temporaryPool->curAddr = temporaryPool->startAddr + size; + + if ((temporaryCache->entries[1].id != -1) && + (temporaryCache->entries[1].addr < temporaryPool->curAddr)) { + if (tableType == SAMPLE_TABLE) { + AudioHeap_DiscardSampleBank(temporaryCache->entries[1].id); + } + + loadStatus[temporaryCache->entries[1].id] = LOAD_STATUS_0; + + switch (tableType) { + case SEQUENCE_TABLE: + AudioHeap_DiscardSequence((s32)temporaryCache->entries[1].id); + break; + + case FONT_TABLE: + AudioHeap_DiscardFont((s32)temporaryCache->entries[1].id); + break; + } + + temporaryCache->entries[1].id = -1; + temporaryCache->entries[1].addr = temporaryPool->startAddr + temporaryPool->size; + } + + temporaryAddr = temporaryCache->entries[0].addr; + break; + + case 1: + temporaryCache->entries[1].addr = + (u8*)((uintptr_t)(temporaryPool->startAddr + temporaryPool->size - size) & ~0xF); + temporaryCache->entries[1].id = id; + temporaryCache->entries[1].size = size; + if ((temporaryCache->entries[0].id != -1) && + (temporaryCache->entries[1].addr < temporaryPool->curAddr)) { + if (tableType == SAMPLE_TABLE) { + AudioHeap_DiscardSampleBank(temporaryCache->entries[0].id); + } + + loadStatus[temporaryCache->entries[0].id] = LOAD_STATUS_0; + + switch (tableType) { + case SEQUENCE_TABLE: + AudioHeap_DiscardSequence(temporaryCache->entries[0].id); + break; + + case FONT_TABLE: + AudioHeap_DiscardFont(temporaryCache->entries[0].id); + break; + } + + temporaryCache->entries[0].id = -1; + temporaryPool->curAddr = temporaryPool->startAddr; + } + + temporaryAddr = temporaryCache->entries[1].addr; + break; + + default: + return NULL; + } + + temporaryCache->nextSide ^= 1; + return temporaryAddr; + } + + persistentAddr = AudioHeap_Alloc(&loadedCache->persistent.pool, size); + loadedCache->persistent.entries[loadedCache->persistent.numEntries].addr = persistentAddr; + + if (persistentAddr == NULL) { + switch (cache) { + case CACHE_EITHER: + return AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, id); + + case CACHE_TEMPORARY: + case CACHE_PERSISTENT: + return NULL; + } + } + + loadedCache->persistent.entries[loadedCache->persistent.numEntries].id = id; + loadedCache->persistent.entries[loadedCache->persistent.numEntries].size = size; + + return loadedCache->persistent.entries[loadedCache->persistent.numEntries++].addr; +} + +void* AudioHeap_SearchCaches(s32 tableType, s32 cache, s32 id) { + void* addr; + + // Always search the permanent cache in addition to the regular ones. + addr = AudioHeap_SearchPermanentCache(tableType, id); + if (addr != NULL) { + return addr; + } + if (cache == CACHE_PERMANENT) { + return NULL; + } + return AudioHeap_SearchRegularCaches(tableType, cache, id); +} + +void* AudioHeap_SearchRegularCaches(s32 tableType, s32 cache, s32 id) { + u32 i; + AudioCache* loadedCache; + AudioTemporaryCache* temporary; + AudioPersistentCache* persistent; + + switch (tableType) { + case SEQUENCE_TABLE: + loadedCache = &gAudioContext.seqCache; + break; + + case FONT_TABLE: + loadedCache = &gAudioContext.fontCache; + break; + + case SAMPLE_TABLE: + loadedCache = &gAudioContext.sampleBankCache; + break; + } + + temporary = &loadedCache->temporary; + + if (cache == CACHE_TEMPORARY) { + if (temporary->entries[0].id == id) { + temporary->nextSide = 1; + return temporary->entries[0].addr; + } else if (temporary->entries[1].id == id) { + temporary->nextSide = 0; + return temporary->entries[1].addr; + } else { + return NULL; + } + } + + persistent = &loadedCache->persistent; + + for (i = 0; i < persistent->numEntries; i++) { + if (persistent->entries[i].id == id) { + return persistent->entries[i].addr; + } + } + + if (cache == CACHE_EITHER) { + return AudioHeap_SearchCaches(tableType, CACHE_TEMPORARY, id); + } + return NULL; +} + +void func_8018C4E4(f32 p, f32 q, u16* out) { + // With the bug below fixed, this mysterious unused function computes two recurrences + // out[0..7] = a_i, out[8..15] = b_i, where + // a_{-2} = b_{-1} = 262159 = 2^18 + 15 + // a_{-1} = b_{-2} = 0 + // a_i = q * a_{i-1} + p * a_{i-2} + // b_i = q * b_{i-1} + p * b_{i-2} + // These grow exponentially if p < -1 or p + |q| > 1. + s32 i; + f32 tmp[16]; + + tmp[0] = (f32)(q * 262159.0f); + tmp[8] = (f32)(p * 262159.0f); + tmp[1] = (f32)((q * p) * 262159.0f); + tmp[9] = (f32)(((p * p) + q) * 262159.0f); + + for (i = 2; i < 8; i++) { + //! @bug value should be stored to tmp[i] and tmp[8 + i], otherwise we read + //! garbage in later loop iterations. + out[i] = q * tmp[i - 2] + p * tmp[i - 1]; + out[8 + i] = q * tmp[6 + i] + p * tmp[7 + i]; + } + + for (i = 0; i < 16; i++) { + out[i] = tmp[i]; + } +} + +void AudioHeap_ClearFilter(s16* filter) { + s32 i; + + for (i = 0; i < 8; i++) { + filter[i] = 0; + } +} + +void AudioHeap_LoadLowPassFilter(s16* filter, s32 cutoff) { + s32 i; + s16* ptr = &gLowPassFilterData[8 * cutoff]; + + for (i = 0; i < 8; i++) { + filter[i] = ptr[i]; + } +} + +void AudioHeap_LoadHighPassFilter(s16* filter, s32 cutoff) { + s32 i; + s16* ptr = &gHighPassFilterData[8 * (cutoff - 1)]; + + for (i = 0; i < 8; i++) { + filter[i] = ptr[i]; + } +} + +void AudioHeap_LoadFilter(s16* filter, s32 lowPassCutoff, s32 highPassCutoff) { + s32 i; + s32 j; + s32 k; + s32 cutOff; + + //! @bug filter is never set if (lowPassCutoff == highPassCutoff) and does not equal 0 + if (lowPassCutoff == 0 && highPassCutoff == 0) { + // Identity filter + AudioHeap_LoadLowPassFilter(filter, 0); + } else if (highPassCutoff == 0) { + AudioHeap_LoadLowPassFilter(filter, lowPassCutoff); + } else if (lowPassCutoff == 0) { + AudioHeap_LoadHighPassFilter(filter, highPassCutoff); + } else { + k = 0; + j = 14; + + cutOff = lowPassCutoff; + if (lowPassCutoff < highPassCutoff) { + + for (i = 1; i < cutOff; i++) { + k += j; + j--; + } + + k += highPassCutoff - lowPassCutoff - 1; + for (i = 0; i < 8; i++) { + //! @bug should be gBandStopFilterData[8 * k + i]; + filter[i] = gBandStopFilterData[k + i]; + } + } else if (highPassCutoff < lowPassCutoff) { + + cutOff = highPassCutoff; + for (i = 1; i < cutOff; i++) { + k += j; + j--; + } + + k += lowPassCutoff - highPassCutoff - 1; + for (i = 0; i < 8; i++) { + //! @bug should be gBandPassFilterData[8 * k + i]; + filter[i] = gBandPassFilterData[k + i]; + } + } + } +} + +void AudioHeap_UpdateReverb(SynthesisReverb* reverb) { +} + +void AudioHeap_UpdateReverbs(void) { + s32 count; + s32 i; + s32 j; + + if (gAudioContext.audioBufferParameters.specUnk4 == 2) { + count = 2; + } else { + count = 1; + } + + for (i = 0; i < gAudioContext.numSynthesisReverbs; i++) { + for (j = 0; j < count; j++) { + AudioHeap_UpdateReverb(&gAudioContext.synthesisReverbs[i]); + } + } +} + +/** + * Clear the Audio Interface Buffers + */ +void AudioHeap_ClearAiBuffers(void) { + s32 curAiBuffferIndex = gAudioContext.curAiBuffferIndex; + s32 i; + + gAudioContext.aiBufLengths[curAiBuffferIndex] = gAudioContext.audioBufferParameters.minAiBufferLength; + + for (i = 0; i < AIBUF_LEN; i++) { + gAudioContext.aiBuffers[curAiBuffferIndex][i] = 0; + } +} + +s32 AudioHeap_ResetStep(void) { + s32 i; + s32 j; + s32 count; + + if (gAudioContext.audioBufferParameters.specUnk4 == 2) { + count = 2; + } else { + count = 1; + } + + switch (gAudioContext.resetStatus) { + case 5: + for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) { + AudioSeq_SequencePlayerDisableAsFinished(&gAudioContext.seqPlayers[i]); + } + gAudioContext.audioResetFadeOutFramesLeft = 2 / count; + gAudioContext.resetStatus--; + break; + + case 4: + if (gAudioContext.audioResetFadeOutFramesLeft != 0) { + gAudioContext.audioResetFadeOutFramesLeft--; + AudioHeap_UpdateReverbs(); + } else { + for (i = 0; i < gAudioContext.numNotes; i++) { + if (gAudioContext.notes[i].noteSubEu.bitField0.enabled && + gAudioContext.notes[i].playbackState.adsr.action.s.state != ADSR_STATE_DISABLED) { + gAudioContext.notes[i].playbackState.adsr.fadeOutVel = + gAudioContext.audioBufferParameters.updatesPerFrameInv; + gAudioContext.notes[i].playbackState.adsr.action.s.release = true; + } + } + gAudioContext.audioResetFadeOutFramesLeft = 8 / count; + gAudioContext.resetStatus--; + } + break; + + case 3: + if (gAudioContext.audioResetFadeOutFramesLeft != 0) { + gAudioContext.audioResetFadeOutFramesLeft--; + AudioHeap_UpdateReverbs(); + } else { + gAudioContext.audioResetFadeOutFramesLeft = 2 / count; + gAudioContext.resetStatus--; + } + break; + + case 2: + AudioHeap_ClearAiBuffers(); + if (gAudioContext.audioResetFadeOutFramesLeft != 0) { + gAudioContext.audioResetFadeOutFramesLeft--; + } else { + gAudioContext.resetStatus--; + AudioHeap_DiscardSampleCaches(); + AudioHeap_DiscardSampleBanks(); + } + break; + + case 1: + AudioHeap_Init(); + gAudioContext.resetStatus = 0; + for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBufLengths); i++) { + gAudioContext.aiBufLengths[i] = gAudioContext.audioBufferParameters.maxAiBufferLength; + for (j = 0; j < AIBUF_LEN; j++) { + gAudioContext.aiBuffers[i][j] = 0; + } + } + break; + } + + if (gAudioContext.resetStatus < 3) { + return false; + } + + return true; +} + +void AudioHeap_Init(void) { + s32 pad1[4]; + s16* addr; + size_t persistentSize; + size_t temporarySize; + size_t cachePoolSize; + size_t miscPoolSize; + u32 intMask; + s32 i; + s32 j; + s32 pad2; + AudioSpec* spec = &gAudioSpecs[gAudioContext.audioResetSpecIdToLoad]; // Audio Specifications + + gAudioContext.sampleDmaCount = 0; + + // audio buffer parameters + gAudioContext.audioBufferParameters.samplingFreq = spec->samplingFreq; + gAudioContext.audioBufferParameters.aiSamplingFreq = + osAiSetFrequency(gAudioContext.audioBufferParameters.samplingFreq); + + gAudioContext.audioBufferParameters.samplesPerFrameTarget = + ALIGN16(gAudioContext.audioBufferParameters.samplingFreq / gAudioContext.refreshRate); + gAudioContext.audioBufferParameters.minAiBufferLength = + gAudioContext.audioBufferParameters.samplesPerFrameTarget - 0x10; + gAudioContext.audioBufferParameters.maxAiBufferLength = + gAudioContext.audioBufferParameters.samplesPerFrameTarget + 0x10; + gAudioContext.audioBufferParameters.updatesPerFrame = + ((gAudioContext.audioBufferParameters.samplesPerFrameTarget + 0x10) / 0xD0) + 1; + gAudioContext.audioBufferParameters.samplesPerUpdate = (gAudioContext.audioBufferParameters.samplesPerFrameTarget / + gAudioContext.audioBufferParameters.updatesPerFrame) & + ~7; + gAudioContext.audioBufferParameters.samplesPerUpdateMax = gAudioContext.audioBufferParameters.samplesPerUpdate + 8; + gAudioContext.audioBufferParameters.samplesPerUpdateMin = gAudioContext.audioBufferParameters.samplesPerUpdate - 8; + gAudioContext.audioBufferParameters.resampleRate = 32000.0f / (s32)gAudioContext.audioBufferParameters.samplingFreq; + gAudioContext.audioBufferParameters.unkUpdatesPerFrameScaled = + (1.0f / 256.0f) / gAudioContext.audioBufferParameters.updatesPerFrame; + gAudioContext.audioBufferParameters.unk_24 = gAudioContext.audioBufferParameters.updatesPerFrame * 0.25f; + gAudioContext.audioBufferParameters.updatesPerFrameInv = 1.0f / gAudioContext.audioBufferParameters.updatesPerFrame; + + // sample dma size + gAudioContext.sampleDmaBufSize1 = spec->sampleDmaBufSize1; + gAudioContext.sampleDmaBufSize2 = spec->sampleDmaBufSize2; + + gAudioContext.numNotes = spec->numNotes; + gAudioContext.audioBufferParameters.numSequencePlayers = spec->numSequencePlayers; + + if (gAudioContext.audioBufferParameters.numSequencePlayers > 5) { + gAudioContext.audioBufferParameters.numSequencePlayers = 5; + } + + gAudioContext.unk_29BC = 8; + gAudioContext.unk_2 = spec->unk_14; + gAudioContext.tempoInternalToExternal = (u32)(gAudioContext.audioBufferParameters.updatesPerFrame * 2880000.0f / + gTatumsPerBeat / gAudioContext.unk_2960); + + gAudioContext.unk_2870 = gAudioContext.refreshRate; + gAudioContext.unk_2870 *= gAudioContext.audioBufferParameters.updatesPerFrame; + gAudioContext.unk_2870 /= gAudioContext.audioBufferParameters.aiSamplingFreq; + gAudioContext.unk_2870 /= gAudioContext.tempoInternalToExternal; + + gAudioContext.audioBufferParameters.specUnk4 = spec->unk_04; + gAudioContext.audioBufferParameters.samplesPerFrameTarget *= gAudioContext.audioBufferParameters.specUnk4; + gAudioContext.audioBufferParameters.maxAiBufferLength *= gAudioContext.audioBufferParameters.specUnk4; + gAudioContext.audioBufferParameters.minAiBufferLength *= gAudioContext.audioBufferParameters.specUnk4; + gAudioContext.audioBufferParameters.updatesPerFrame *= gAudioContext.audioBufferParameters.specUnk4; + + if (gAudioContext.audioBufferParameters.specUnk4 >= 2) { + gAudioContext.audioBufferParameters.maxAiBufferLength -= 0x10; + } + + // Determine the maximum allowable number of audio command list entries for the rsp microcode + gAudioContext.maxAudioCmds = + gAudioContext.numNotes * 20 * gAudioContext.audioBufferParameters.updatesPerFrame + spec->numReverbs * 30 + 800; + + // Calculate sizes for various caches on the audio heap + persistentSize = + spec->persistentSeqCacheSize + spec->persistentFontCacheSize + spec->persistentSampleBankCacheSize + 0x10; + temporarySize = + spec->temporarySeqCacheSize + spec->temporaryFontCacheSize + spec->temporarySampleBankCacheSize + 0x10; + cachePoolSize = persistentSize + temporarySize; + miscPoolSize = gAudioContext.audioSessionPool.size - cachePoolSize - 0x100; + + if (gAudioContext.externalPool.startAddr != NULL) { + gAudioContext.externalPool.curAddr = gAudioContext.externalPool.startAddr; + } + + // Session Pool Split (split into Cache and Misc heaps) + gAudioContext.sessionPoolSplit.miscPoolSize = miscPoolSize; + gAudioContext.sessionPoolSplit.cachePoolSize = cachePoolSize; + AudioHeap_InitSessionPool(&gAudioContext.sessionPoolSplit); + + // Cache Pool Split (Split into Persistent and Temporary heaps) + gAudioContext.cachePoolSplit.persistentCommonPoolSize = persistentSize; + gAudioContext.cachePoolSplit.temporaryCommonPoolSize = temporarySize; + AudioHeap_InitCachePool(&gAudioContext.cachePoolSplit); + + // Persistent Pool Split (Split into Sequences, SoundFonts, Samples) + gAudioContext.persistentCommonPoolSplit.seqCacheSize = spec->persistentSeqCacheSize; + gAudioContext.persistentCommonPoolSplit.fontCacheSize = spec->persistentFontCacheSize; + gAudioContext.persistentCommonPoolSplit.sampleBankCacheSize = spec->persistentSampleBankCacheSize; + AudioHeap_InitPersistentCache(&gAudioContext.persistentCommonPoolSplit); + + // Temporary Pool Split (Split into Sequences, SoundFonts, Samples) + gAudioContext.temporaryCommonPoolSplit.seqCacheSize = spec->temporarySeqCacheSize; + gAudioContext.temporaryCommonPoolSplit.fontCacheSize = spec->temporaryFontCacheSize; + gAudioContext.temporaryCommonPoolSplit.sampleBankCacheSize = spec->temporarySampleBankCacheSize; + AudioHeap_InitTemporaryCache(&gAudioContext.temporaryCommonPoolSplit); + + AudioHeap_ResetLoadStatus(); + + // Initialize notes + gAudioContext.notes = AudioHeap_AllocZeroed(&gAudioContext.miscPool, gAudioContext.numNotes * sizeof(Note)); + AudioPlayback_NoteInitAll(); + AudioPlayback_InitNoteFreeList(); + gAudioContext.noteSubsEu = + AudioHeap_AllocZeroed(&gAudioContext.miscPool, gAudioContext.audioBufferParameters.updatesPerFrame * + gAudioContext.numNotes * sizeof(NoteSubEu)); + + // Initialize audio binary interface command list buffer + for (j = 0; j < ARRAY_COUNT(gAudioContext.abiCmdBufs); j++) { + gAudioContext.abiCmdBufs[j] = + AudioHeap_AllocDmaMemoryZeroed(&gAudioContext.miscPool, gAudioContext.maxAudioCmds * sizeof(u64)); + } + + // Initialize unk_3520 (fadeOutVelocities for ADSR) + gAudioContext.unk_3520 = AudioHeap_Alloc(&gAudioContext.miscPool, 0x100 * sizeof(f32)); + func_8018B10C(); + + // Initialize reverbs + for (i = 0; i < ARRAY_COUNT(gAudioContext.synthesisReverbs); i++) { + gAudioContext.synthesisReverbs[i].useReverb = 0; + } + + gAudioContext.numSynthesisReverbs = spec->numReverbs; + for (i = 0; i < gAudioContext.numSynthesisReverbs; i++) { + AudioHeap_InitReverb(i, &spec->reverbSettings[i], 1); + } + + // Initialize sequence players + AudioSeq_InitSequencePlayers(); + for (j = 0; j < gAudioContext.audioBufferParameters.numSequencePlayers; j++) { + AudioSeq_InitSequencePlayerChannels(j); + AudioSeq_ResetSequencePlayer(&gAudioContext.seqPlayers[j]); + } + + // Initialize two additional caches on the audio heap to store individual audio samples + AudioHeap_InitSampleCaches(spec->persistentSampleCacheSize, spec->temporarySampleCacheSize); + AudioLoad_InitSampleDmaBuffers(gAudioContext.numNotes); + + // Initalize Loads + gAudioContext.preloadSampleStackTop = 0; + AudioLoad_InitSlowLoads(); + AudioLoad_InitScriptLoads(); + AudioLoad_InitAsyncLoads(); + gAudioContext.unk_4 = 0x1000; + AudioLoad_LoadPermanentSamples(); + + intMask = osSetIntMask(1); + osWritebackDCacheAll(); + osSetIntMask(intMask); +} + +void* AudioHeap_SearchPermanentCache(s32 tableType, s32 id) { + s32 i; + + for (i = 0; i < gAudioContext.permanentPool.count; i++) { + if (gAudioContext.permanentEntries[i].tableType == tableType && gAudioContext.permanentEntries[i].id == id) { + return gAudioContext.permanentEntries[i].addr; + } + } + return NULL; +} + +void* AudioHeap_AllocPermanent(s32 tableType, s32 id, size_t size) { + void* addr; + s32 index = gAudioContext.permanentPool.count; + + addr = AudioHeap_Alloc(&gAudioContext.permanentPool, size); + gAudioContext.permanentEntries[index].addr = addr; + + if (addr == NULL) { + return NULL; + } + + gAudioContext.permanentEntries[index].tableType = tableType; + gAudioContext.permanentEntries[index].id = id; + gAudioContext.permanentEntries[index].size = size; + //! @bug UB: missing return. "addr" is in v0 at this point, but doing an + // explicit return uses an additional register. + // return addr; +} + +void* AudioHeap_AllocSampleCache(size_t size, s32 sampleBankId, void* sampleAddr, s8 medium, s32 cache) { + SampleCacheEntry* entry; + + if (cache == CACHE_TEMPORARY) { + entry = AudioHeap_AllocTemporarySampleCacheEntry(size); + } else { + entry = AudioHeap_AllocPersistentSampleCacheEntry(size); + } + + if (entry != NULL) { + entry->sampleBankId = sampleBankId; + entry->sampleAddr = sampleAddr; + entry->origMedium = medium; + return entry->allocatedAddr; + } + return NULL; +} + +/** + * Initializes the persistent and temporary caches used for individual samples. Will attempt to use heap space available + * on the external pool. If no external pool is provided, then default to using space on the misc heap. + */ +void AudioHeap_InitSampleCaches(size_t persistentSampleCacheSize, size_t temporarySampleCacheSize) { + void* addr; + + addr = AudioHeap_AllocAttemptExternal(&gAudioContext.miscPool, persistentSampleCacheSize); + if (addr == NULL) { + gAudioContext.persistentSampleCache.pool.size = 0; + } else { + AudioHeap_AllocPoolInit(&gAudioContext.persistentSampleCache.pool, addr, persistentSampleCacheSize); + } + + addr = AudioHeap_AllocAttemptExternal(&gAudioContext.miscPool, temporarySampleCacheSize); + if (addr == NULL) { + gAudioContext.temporarySampleCache.pool.size = 0; + } else { + AudioHeap_AllocPoolInit(&gAudioContext.temporarySampleCache.pool, addr, temporarySampleCacheSize); + } + + gAudioContext.persistentSampleCache.numEntries = 0; + gAudioContext.temporarySampleCache.numEntries = 0; +} + +SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(size_t size) { + s32 pad2[2]; + void* addr; + s32 pad3[2]; + u8* allocAfter; + u8* allocBefore; + s32 pad1; + s32 index; + s32 i; + SampleCacheEntry* entry; + AudioPreloadReq* preload; + AudioSampleCache* cache; + u8* startAddr; + u8* endAddr; + + cache = &gAudioContext.temporarySampleCache; + allocBefore = cache->pool.curAddr; + addr = AudioHeap_Alloc(&cache->pool, size); + if (addr == NULL) { + // Reset the heap and try again. We still keep pointers to within the + // heap, so we have to be careful to discard existing overlapping + // allocations further down. + u8* oldAddr = cache->pool.curAddr; + + cache->pool.curAddr = cache->pool.startAddr; + addr = AudioHeap_Alloc(&cache->pool, size); + if (addr == NULL) { + cache->pool.curAddr = oldAddr; + return NULL; + } + allocBefore = cache->pool.startAddr; + } + + allocAfter = cache->pool.curAddr; + + index = -1; + for (i = 0; i < gAudioContext.preloadSampleStackTop; i++) { + preload = &gAudioContext.preloadSampleStack[i]; + if (preload->isFree == false) { + startAddr = preload->ramAddr; + endAddr = preload->ramAddr + preload->sample->size - 1; + + if ((endAddr < allocBefore) && (startAddr < allocBefore)) { + continue; + } + if ((endAddr >= allocAfter) && (startAddr >= allocAfter)) { + continue; + } + + // Overlap, skip this preload. + preload->isFree = true; + } + } + + for (i = 0; i < cache->numEntries; i++) { + if (!cache->entries[i].inUse) { + continue; + } + + startAddr = cache->entries[i].allocatedAddr; + endAddr = startAddr + cache->entries[i].size - 1; + + if ((endAddr < allocBefore) && (startAddr < allocBefore)) { + continue; + } + if ((endAddr >= allocAfter) && (startAddr >= allocAfter)) { + continue; + } + + // Overlap, discard existing entry. + AudioHeap_DiscardSampleCacheEntry(&cache->entries[i]); + cache->entries[i].inUse = false; + if (index == -1) { + index = i; + } + } + + if (index == -1) { + for (i = 0; i < cache->numEntries; i++) { + if (!cache->entries[i].inUse) { + break; + } + } + + index = i; + if (index == cache->numEntries) { + if (cache->numEntries == 128) { + return NULL; + } + cache->numEntries++; + } + } + + entry = &cache->entries[index]; + entry->inUse = 1; + entry->allocatedAddr = addr; + entry->size = size; + + return entry; +} + +void AudioHeap_UnapplySampleCacheForFont(SampleCacheEntry* entry, s32 fontId) { + Drum* drum; + Instrument* inst; + SoundFontSound* sfx; + s32 instId; + s32 drumId; + s32 sfxId; + + for (instId = 0; instId < gAudioContext.soundFonts[fontId].numInstruments; instId++) { + inst = AudioPlayback_GetInstrumentInner(fontId, instId); + if (inst != NULL) { + if (inst->normalRangeLo != 0) { + AudioHeap_UnapplySampleCache(entry, inst->lowNotesSound.sample); + } + if (inst->normalRangeHi != 0x7F) { + AudioHeap_UnapplySampleCache(entry, inst->highNotesSound.sample); + } + AudioHeap_UnapplySampleCache(entry, inst->normalNotesSound.sample); + } + } + + for (drumId = 0; drumId < gAudioContext.soundFonts[fontId].numDrums; drumId++) { + drum = AudioPlayback_GetDrum(fontId, drumId); + if (drum != NULL) { + AudioHeap_UnapplySampleCache(entry, drum->sound.sample); + } + } + + for (sfxId = 0; sfxId < gAudioContext.soundFonts[fontId].numSfx; sfxId++) { + sfx = AudioPlayback_GetSfx(fontId, sfxId); + if (sfx != NULL) { + AudioHeap_UnapplySampleCache(entry, sfx->sample); + } + } +} + +void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry) { + s32 numFonts; + s32 sampleBankId1; + s32 sampleBankId2; + s32 fontId; + + numFonts = gAudioContext.soundFontTable->numEntries; + for (fontId = 0; fontId < numFonts; fontId++) { + sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1; + sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2; + if (((sampleBankId1 != 0xFF) && (entry->sampleBankId == sampleBankId1)) || + ((sampleBankId2 != 0xFF) && (entry->sampleBankId == sampleBankId2)) || entry->sampleBankId == 0 || + entry->sampleBankId == 0xFE) { + if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, fontId) != NULL) { + if (1) {} + if (AudioLoad_IsFontLoadComplete(fontId) != 0) { + AudioHeap_UnapplySampleCacheForFont(entry, fontId); + } + } + } + } +} + +void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, SoundFontSample* sample) { + if (sample != NULL) { + if (sample->sampleAddr == entry->allocatedAddr) { + sample->sampleAddr = entry->sampleAddr; + sample->medium = entry->origMedium; + } + } +} + +SampleCacheEntry* AudioHeap_AllocPersistentSampleCacheEntry(size_t size) { + AudioSampleCache* cache; + SampleCacheEntry* entry; + void* addr; + + cache = &gAudioContext.persistentSampleCache; + addr = AudioHeap_Alloc(&cache->pool, size); + if (addr == NULL) { + return NULL; + } + + if (cache->numEntries == 128) { + return NULL; + } + + entry = &cache->entries[cache->numEntries]; + entry->inUse = true; + entry->allocatedAddr = addr; + entry->size = size; + cache->numEntries++; + + return entry; +} + +void AudioHeap_DiscardSampleCacheForFont(SampleCacheEntry* entry, s32 sampleBankId1, s32 sampleBankId2, s32 fontId) { + if ((entry->sampleBankId == sampleBankId1) || (entry->sampleBankId == sampleBankId2) || + (entry->sampleBankId == 0)) { + AudioHeap_UnapplySampleCacheForFont(entry, fontId); + } +} + +void AudioHeap_DiscardSampleCaches(void) { + s32 numFonts; + s32 sampleBankId1; + s32 sampleBankId2; + s32 fontId; + s32 j; + + numFonts = gAudioContext.soundFontTable->numEntries; + for (fontId = 0; fontId < numFonts; fontId++) { + sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1; + sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2; + if ((sampleBankId1 == 0xFF) && (sampleBankId2 == 0xFF)) { + continue; + } + if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_PERMANENT, fontId) == NULL || + !AudioLoad_IsFontLoadComplete(fontId)) { + continue; + } + + for (j = 0; j < gAudioContext.persistentSampleCache.numEntries; j++) { + AudioHeap_DiscardSampleCacheForFont(&gAudioContext.persistentSampleCache.entries[j], sampleBankId1, + sampleBankId2, fontId); + } + for (j = 0; j < gAudioContext.temporarySampleCache.numEntries; j++) { + AudioHeap_DiscardSampleCacheForFont(&gAudioContext.temporarySampleCache.entries[j], sampleBankId1, + sampleBankId2, fontId); + } + } +} + +typedef struct { + uintptr_t oldAddr; + uintptr_t newAddr; + size_t size; + u8 newMedium; +} StorageChange; + +void AudioHeap_ChangeStorage(StorageChange* change, SoundFontSample* sample) { + if (sample != NULL && ((sample->medium == change->newMedium) || (D_801FD120 != 1)) && + ((sample->medium == MEDIUM_RAM) || (D_801FD120 != 0))) { + uintptr_t startAddr = change->oldAddr; + uintptr_t endAddr = change->oldAddr + change->size; + + if (startAddr <= (uintptr_t)sample->sampleAddr && (uintptr_t)sample->sampleAddr < endAddr) { + sample->sampleAddr = sample->sampleAddr - startAddr + change->newAddr; + if (D_801FD120 == 0) { + sample->medium = change->newMedium; + } else { + sample->medium = MEDIUM_RAM; + } + } + } +} + +void AudioHeap_DiscardSampleBank(s32 sampleBankId) { + D_801FD120 = 0; + AudioHeap_ApplySampleBankCacheInternal(false, sampleBankId); +} + +void AudioHeap_ApplySampleBankCache(s32 sampleBankId) { + D_801FD120 = 1; + AudioHeap_ApplySampleBankCacheInternal(true, sampleBankId); +} + +void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId) { + AudioTable* sampleBankTable; + AudioTableEntry* entry; + s32 numFonts; + s32 instId; + s32 drumId; + s32 sfxId; + StorageChange change; + s32 sampleBankId1; + s32 sampleBankId2; + s32 fontId; + Drum* drum; + Instrument* inst; + SoundFontSound* sfx; + uintptr_t* newAddr; + s32 pad[4]; + + sampleBankTable = gAudioContext.sampleBankTable; + numFonts = gAudioContext.soundFontTable->numEntries; + change.oldAddr = AudioHeap_SearchCaches(SAMPLE_TABLE, CACHE_EITHER, sampleBankId); + if (change.oldAddr == 0) { + return; + } + + entry = &sampleBankTable->entries[sampleBankId]; + change.size = entry->size; + change.newMedium = entry->medium; + change.newAddr = entry->romAddr; + + newAddr = &change.oldAddr; + if (apply && (apply == true)) { + uintptr_t oldAddr; + + oldAddr = change.newAddr; + + change.newAddr = *newAddr; + change.oldAddr = oldAddr; + } + + for (fontId = 0; fontId < numFonts; fontId++) { + sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1; + sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2; + if ((sampleBankId1 != 0xFF) || (sampleBankId2 != 0xFF)) { + if (!AudioLoad_IsFontLoadComplete(fontId) || + AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, fontId) == NULL) { + continue; + } + + if (sampleBankId1 == sampleBankId) { + } else if (sampleBankId2 == sampleBankId) { + } else { + continue; + } + + for (instId = 0; instId < gAudioContext.soundFonts[fontId].numInstruments; instId++) { + inst = AudioPlayback_GetInstrumentInner(fontId, instId); + if (inst != NULL) { + if (inst->normalRangeLo != 0) { + AudioHeap_ChangeStorage(&change, inst->lowNotesSound.sample); + } + if (inst->normalRangeHi != 0x7F) { + AudioHeap_ChangeStorage(&change, inst->highNotesSound.sample); + } + AudioHeap_ChangeStorage(&change, inst->normalNotesSound.sample); + } + } + + for (drumId = 0; drumId < gAudioContext.soundFonts[fontId].numDrums; drumId++) { + drum = AudioPlayback_GetDrum(fontId, drumId); + if (drum != NULL) { + AudioHeap_ChangeStorage(&change, drum->sound.sample); + } + } + + for (sfxId = 0; sfxId < gAudioContext.soundFonts[fontId].numSfx; sfxId++) { + sfx = AudioPlayback_GetSfx(fontId, sfxId); + if (sfx != NULL) { + AudioHeap_ChangeStorage(&change, sfx->sample); + } + } + } + } +} + +void AudioHeap_DiscardSampleBanks(void) { + AudioCache* cache; + AudioPersistentCache* persistent; + AudioTemporaryCache* temporary; + u32 i; + + cache = &gAudioContext.sampleBankCache; + temporary = &cache->temporary; + + if (temporary->entries[0].id != -1) { + AudioHeap_DiscardSampleBank(temporary->entries[0].id); + } + + if (temporary->entries[1].id != -1) { + AudioHeap_DiscardSampleBank(temporary->entries[1].id); + } + + persistent = &cache->persistent; + for (i = 0; i < persistent->numEntries; i++) { + AudioHeap_DiscardSampleBank(persistent->entries[i].id); + } +} + +void AudioHeap_SetReverbData(s32 reverbIndex, u32 dataType, s32 data, s32 flags) { + s32 windowSize; + SynthesisReverb* reverb = &gAudioContext.synthesisReverbs[reverbIndex]; + + switch (dataType) { + case 0: + AudioHeap_InitReverb(reverbIndex, (ReverbSettings*)data, 0); + break; + case 1: + if (data < 4) { + data = 4; + } + + windowSize = data * 64; + if (windowSize < 0x100) { + windowSize = 0x100; + } + + windowSize /= reverb->downsampleRate; + + if (flags == 0) { + if (reverb->unk_1E >= (data / reverb->downsampleRate)) { + if ((reverb->nextRingBufPos >= windowSize) || (reverb->unk_24 >= windowSize)) { + reverb->nextRingBufPos = 0; + reverb->unk_24 = 0; + } + } else { + break; + } + } + + reverb->windowSize = windowSize; + + if ((reverb->downsampleRate != 1) || reverb->unk_18) { + reverb->unk_0E = 0x8000 / reverb->downsampleRate; + if (reverb->unk_30 == NULL) { + reverb->unk_30 = AudioHeap_AllocZeroed(&gAudioContext.miscPool, 0x20); + reverb->unk_34 = AudioHeap_AllocZeroed(&gAudioContext.miscPool, 0x20); + reverb->unk_38 = AudioHeap_AllocZeroed(&gAudioContext.miscPool, 0x20); + reverb->unk_3C = AudioHeap_AllocZeroed(&gAudioContext.miscPool, 0x20); + if (reverb->unk_3C == NULL) { + reverb->downsampleRate = 1; + } + } + } + break; + case 2: + gAudioContext.synthesisReverbs[reverbIndex].unk_0C = data; + break; + case 3: + gAudioContext.synthesisReverbs[reverbIndex].unk_16 = data; + break; + case 4: + gAudioContext.synthesisReverbs[reverbIndex].unk_0A = data; + break; + case 5: + gAudioContext.synthesisReverbs[reverbIndex].leakRtl = data; + break; + case 6: + gAudioContext.synthesisReverbs[reverbIndex].leakLtr = data; + break; + case 7: + if (data != 0) { + if ((flags != 0) || (reverb->unk_278 == 0)) { + reverb->filterLeftState = AudioHeap_AllocDmaMemoryZeroed(&gAudioContext.miscPool, 0x40); + reverb->unk_278 = AudioHeap_AllocDmaMemory(&gAudioContext.miscPool, 0x10); + } + + reverb->filterLeft = reverb->unk_278; + if (reverb->filterLeft != 0) { + AudioHeap_LoadLowPassFilter(reverb->filterLeft, data); + } + } else { + reverb->filterLeft = 0; + + if (flags != 0) { + reverb->unk_278 = 0; + } + } + + break; + case 8: + if (data != 0) { + if ((flags != 0) || (reverb->unk_27C == 0)) { + reverb->filterRightState = AudioHeap_AllocDmaMemoryZeroed(&gAudioContext.miscPool, 0x40); + reverb->unk_27C = AudioHeap_AllocDmaMemory(&gAudioContext.miscPool, 0x10); + } + reverb->filterRight = reverb->unk_27C; + if (reverb->unk_27C != 0) { + AudioHeap_LoadLowPassFilter(reverb->unk_27C, data); + } + } else { + reverb->filterRight = 0; + if (flags != 0) { + reverb->unk_27C = 0; + } + } + break; + case 9: + reverb->unk_19 = data; + if (data == 0) { + reverb->unk_18 = false; + } else { + reverb->unk_18 = true; + } + break; + default: + break; + } +} + +void AudioHeap_InitReverb(s32 reverbIndex, ReverbSettings* settings, s32 flags) { + SynthesisReverb* reverb = &gAudioContext.synthesisReverbs[reverbIndex]; + + if (flags != 0) { + reverb->unk_1E = settings->windowSize / settings->downsampleRate; + reverb->unk_30 = 0; + } else if (reverb->unk_1E < (settings->windowSize / settings->downsampleRate)) { + return; + } + + reverb->downsampleRate = settings->downsampleRate; + reverb->unk_18 = false; + reverb->unk_19 = 0; + reverb->unk_1A = 0; + reverb->unk_1C = 0; + AudioHeap_SetReverbData(reverbIndex, 1, settings->windowSize, flags); + reverb->unk_0C = settings->unk_4; + reverb->unk_0A = settings->unk_A; + reverb->unk_14 = settings->unk_6 << 6; + reverb->unk_16 = settings->unk_8; + reverb->leakRtl = settings->leakRtl; + reverb->leakLtr = settings->leakLtr; + reverb->unk_05 = settings->unk_10; + reverb->unk_08 = settings->unk_12; + reverb->useReverb = 8; + + if (flags != 0) { + reverb->leftRingBuf = AudioHeap_AllocZeroedAttemptExternal(&gAudioContext.miscPool, reverb->windowSize * 2); + reverb->rightRingBuf = AudioHeap_AllocZeroedAttemptExternal(&gAudioContext.miscPool, reverb->windowSize * 2); + reverb->resampleFlags = 1; + reverb->nextRingBufPos = 0; + reverb->unk_24 = 0; + reverb->curFrame = 0; + reverb->framesToIgnore = 2; + } + + reverb->sound.sample = &reverb->sample; + reverb->sample.loop = &reverb->loop; + reverb->sound.tuning = 1.0f; + reverb->sample.codec = CODEC_REVERB; + reverb->sample.medium = MEDIUM_RAM; + reverb->sample.size = reverb->windowSize * 2; + reverb->sample.sampleAddr = (u8*)reverb->leftRingBuf; + reverb->loop.start = 0; + reverb->loop.count = 1; + reverb->loop.end = reverb->windowSize; + + AudioHeap_SetReverbData(reverbIndex, 7, settings->lowPassFilterCutoffLeft, flags); + AudioHeap_SetReverbData(reverbIndex, 8, settings->lowPassFilterCutoffRight, flags); +} diff --git a/src/code/audio/audio_init_params.c b/src/code/audio/audio_init_params.c index 4e6ef9dfbb..b407ef7c98 100644 --- a/src/code/audio/audio_init_params.c +++ b/src/code/audio/audio_init_params.c @@ -7,6 +7,6 @@ const s16 gAudioTatumInit[] = { const AudioContextInitSizes gAudioContextInitSizes = { 0x137F00, // heapSize - 0x1C480, // initPoolSize + 0x1C480, // mainPoolSplitSize 0x1A000, // permanentPoolSize }; diff --git a/src/code/audio/audio_seqplayer.c b/src/code/audio/audio_seqplayer.c index c132ba6a6b..e57ad19b5a 100644 --- a/src/code/audio/audio_seqplayer.c +++ b/src/code/audio/audio_seqplayer.c @@ -20,7 +20,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197C8C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197D24.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_SequencePlayerDisableAsFinished.s") #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_SequencePlayerDisable.s") @@ -66,8 +66,8 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_ResetSequencePlayer.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_8019AC10.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_InitSequencePlayerChannels.s") #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_8019ACEC.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_8019ADBC.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_InitSequencePlayers.s") diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 4d38c01834..88487c9168 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -3548,59 +3548,59 @@ 0x8018AE34:("func_8018AE34",), 0x8018B0F0:("func_8018B0F0",), 0x8018B10C:("func_8018B10C",), - 0x8018B250:("func_8018B250",), + 0x8018B250:("AudioHeap_ResetLoadStatus",), 0x8018B318:("AudioHeap_DiscardFont",), - 0x8018B3FC:("func_8018B3FC",), - 0x8018B474:("func_8018B474",), + 0x8018B3FC:("AudioHeap_ReleaseNotesForFont",), + 0x8018B474:("AudioHeap_DiscardSequence",), 0x8018B4F8:("AudioHeap_WritebackDCache",), - 0x8018B520:("func_8018B520",), + 0x8018B520:("AudioHeap_AllocZeroedAttemptExternal",), 0x8018B578:("AudioHeap_AllocAttemptExternal",), 0x8018B5D0:("AudioHeap_AllocDmaMemory",), - 0x8018B608:("func_8018B608",), + 0x8018B608:("AudioHeap_AllocDmaMemoryZeroed",), 0x8018B640:("AudioHeap_AllocZeroed",), - 0x8018B69C:("func_8018B69C",), + 0x8018B69C:("AudioHeap_TestAlloc",), 0x8018B6E8:("AudioHeap_Alloc",), 0x8018B740:("AudioHeap_AllocPoolInit",), - 0x8018B768:("func_8018B768",), - 0x8018B77C:("func_8018B77C",), - 0x8018B7AC:("func_8018B7AC",), - 0x8018B7BC:("func_8018B7BC",), + 0x8018B768:("AudioHeap_ClearPersistentCache",), + 0x8018B77C:("AudioHeap_ClearTemporaryCache",), + 0x8018B7AC:("AudioHeap_ResetPool",), + 0x8018B7BC:("AudioHeap_PopCache",), 0x8018B8FC:("AudioHeap_InitMainPool",), - 0x8018B95C:("func_8018B95C",), - 0x8018B9E0:("func_8018B9E0",), - 0x8018BA64:("func_8018BA64",), - 0x8018BB28:("func_8018BB28",), + 0x8018B95C:("AudioHeap_InitSessionPool",), + 0x8018B9E0:("AudioHeap_InitCachePool",), + 0x8018BA64:("AudioHeap_InitPersistentCache",), + 0x8018BB28:("AudioHeap_InitTemporaryCache",), 0x8018BBEC:("AudioHeap_AllocCached",), 0x8018C380:("AudioHeap_SearchCaches",), - 0x8018C3D8:("func_8018C3D8",), + 0x8018C3D8:("AudioHeap_SearchRegularCaches",), 0x8018C4E4:("func_8018C4E4",), - 0x8018C8B8:("func_8018C8B8",), - 0x8018C8E8:("func_8018C8E8",), - 0x8018C93C:("func_8018C93C",), - 0x8018C994:("func_8018C994",), - 0x8018CB70:("func_8018CB70",), - 0x8018CB78:("func_8018CB78",), - 0x8018CC3C:("func_8018CC3C",), + 0x8018C8B8:("AudioHeap_ClearFilter",), + 0x8018C8E8:("AudioHeap_LoadLowPassFilter",), + 0x8018C93C:("AudioHeap_LoadHighPassFilter",), + 0x8018C994:("AudioHeap_LoadFilter",), + 0x8018CB70:("AudioHeap_UpdateReverb",), + 0x8018CB78:("AudioHeap_UpdateReverbs",), + 0x8018CC3C:("AudioHeap_ClearAiBuffers",), 0x8018CCA8:("AudioHeap_ResetStep",), - 0x8018CFAC:("func_8018CFAC",), + 0x8018CFAC:("AudioHeap_Init",), 0x8018D57C:("AudioHeap_SearchPermanentCache",), 0x8018D5D4:("AudioHeap_AllocPermanent",), 0x8018D658:("AudioHeap_AllocSampleCache",), - 0x8018D6C8:("func_8018D6C8",), - 0x8018D760:("func_8018D760",), - 0x8018DA50:("func_8018DA50",), - 0x8018DBC4:("func_8018DBC4",), - 0x8018DCB4:("func_8018DCB4",), - 0x8018DCF8:("func_8018DCF8",), - 0x8018DD98:("func_8018DD98",), - 0x8018DDD4:("func_8018DDD4",), - 0x8018DF24:("func_8018DF24",), - 0x8018DFE0:("func_8018DFE0",), + 0x8018D6C8:("AudioHeap_InitSampleCaches",), + 0x8018D760:("AudioHeap_AllocTemporarySampleCacheEntry",), + 0x8018DA50:("AudioHeap_UnapplySampleCacheForFont",), + 0x8018DBC4:("AudioHeap_DiscardSampleCacheEntry",), + 0x8018DCB4:("AudioHeap_UnapplySampleCache",), + 0x8018DCF8:("AudioHeap_AllocPersistentSampleCacheEntry",), + 0x8018DD98:("AudioHeap_DiscardSampleCacheForFont",), + 0x8018DDD4:("AudioHeap_DiscardSampleCaches",), + 0x8018DF24:("AudioHeap_ChangeStorage",), + 0x8018DFE0:("AudioHeap_DiscardSampleBank",), 0x8018E00C:("AudioHeap_ApplySampleBankCache",), - 0x8018E03C:("func_8018E03C",), - 0x8018E2A8:("func_8018E2A8",), - 0x8018E344:("func_8018E344",), - 0x8018E8C8:("func_8018E8C8",), + 0x8018E03C:("AudioHeap_ApplySampleBankCacheInternal",), + 0x8018E2A8:("AudioHeap_DiscardSampleBanks",), + 0x8018E344:("AudioHeap_SetReverbData",), + 0x8018E8C8:("AudioHeap_InitReverb",), 0x8018EB60:("AudioLoad_DecreaseSampleDmaTtls",), 0x8018EC4C:("AudioLoad_DmaSampleData",), 0x8018EF88:("AudioLoad_InitSampleDmaBuffers",), @@ -3777,7 +3777,7 @@ 0x80197B14:("func_80197B14",), 0x80197C0C:("func_80197C0C",), 0x80197C8C:("func_80197C8C",), - 0x80197D24:("func_80197D24",), + 0x80197D24:("AudioSeq_SequencePlayerDisableAsFinished",), 0x80197D4C:("AudioSeq_SequencePlayerDisable",), 0x80197E08:("AudioSeq_AudioListPushBack",), 0x80197E48:("AudioSeq_AudioListPopBack",), @@ -3800,9 +3800,9 @@ 0x8019AA3C:("func_8019AA3C",), 0x8019AAF0:("func_8019AAF0",), 0x8019AB40:("AudioSeq_ResetSequencePlayer",), - 0x8019AC10:("func_8019AC10",), + 0x8019AC10:("AudioSeq_InitSequencePlayerChannels",), 0x8019ACEC:("func_8019ACEC",), - 0x8019ADBC:("func_8019ADBC",), + 0x8019ADBC:("AudioSeq_InitSequencePlayers",), 0x8019AE40:("func_8019AE40",), 0x8019AEC0:("func_8019AEC0",), 0x8019AF00:("func_8019AF00",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index f88c541bd8..07e57be02f 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -2461,7 +2461,7 @@ 0x801DB8B8:("D_801DB8B8","UNK_TYPE1","",0x1), 0x801DB900:("D_801DB900","UNK_TYPE1","",0x1), 0x801DB930:("D_801DB930","UNK_PTR","",0x4), - 0x801DB958:("D_801DB958","AudioSpec","[21]",0x498), + 0x801DB958:("gAudioSpecs","AudioSpec","[21]",0x498), 0x801DBDF0:("D_801DBDF0","f32","",0x4), 0x801DBDF4:("jtbl_801DBDF4","UNK_PTR","",0x4), 0x801DBE68:("D_801DBE68","f32","",0x4), diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index d8b33b84bf..fa1f63c91a 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -3064,61 +3064,59 @@ asm/non_matchings/code/audio_synthesis/func_8018A768.s,func_8018A768,0x8018A768, asm/non_matchings/code/audio_synthesis/func_8018A808.s,func_8018A808,0x8018A808,0x12F asm/non_matchings/code/audio_synthesis/func_8018ACC4.s,func_8018ACC4,0x8018ACC4,0x5C asm/non_matchings/code/audio_synthesis/func_8018AE34.s,func_8018AE34,0x8018AE34,0xAF -asm/non_matchings/code/audio_heap/func_8018B0F0.s,func_8018B0F0,0x8018B0F0,0x7 -asm/non_matchings/code/audio_heap/func_8018B10C.s,func_8018B10C,0x8018B10C,0x51 -asm/non_matchings/code/audio_heap/func_8018B250.s,func_8018B250,0x8018B250,0x32 +asm/non_matchings/code/audio_heap/AudioHeap_ResetLoadStatus.s,AudioHeap_ResetLoadStatus,0x8018B250,0x32 asm/non_matchings/code/audio_heap/AudioHeap_DiscardFont.s,AudioHeap_DiscardFont,0x8018B318,0x39 -asm/non_matchings/code/audio_heap/func_8018B3FC.s,func_8018B3FC,0x8018B3FC,0x1E -asm/non_matchings/code/audio_heap/func_8018B474.s,func_8018B474,0x8018B474,0x21 +asm/non_matchings/code/audio_heap/AudioHeap_ReleaseNotesForFont.s,AudioHeap_ReleaseNotesForFont,0x8018B3FC,0x1E +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSequence.s,AudioHeap_DiscardSequence,0x8018B474,0x21 asm/non_matchings/code/audio_heap/AudioHeap_WritebackDCache.s,AudioHeap_WritebackDCache,0x8018B4F8,0xA -asm/non_matchings/code/audio_heap/func_8018B520.s,func_8018B520,0x8018B520,0x16 +asm/non_matchings/code/audio_heap/AudioHeap_AllocZeroedAttemptExternal.s,AudioHeap_AllocZeroedAttemptExternal,0x8018B520,0x16 asm/non_matchings/code/audio_heap/AudioHeap_AllocAttemptExternal.s,AudioHeap_AllocAttemptExternal,0x8018B578,0x16 asm/non_matchings/code/audio_heap/AudioHeap_AllocDmaMemory.s,AudioHeap_AllocDmaMemory,0x8018B5D0,0xE -asm/non_matchings/code/audio_heap/func_8018B608.s,func_8018B608,0x8018B608,0xE +asm/non_matchings/code/audio_heap/AudioHeap_AllocDmaMemoryZeroed.s,AudioHeap_AllocDmaMemoryZeroed,0x8018B608,0xE asm/non_matchings/code/audio_heap/AudioHeap_AllocZeroed.s,AudioHeap_AllocZeroed,0x8018B640,0x17 -asm/non_matchings/code/audio_heap/func_8018B69C.s,func_8018B69C,0x8018B69C,0x13 -asm/non_matchings/code/audio_heap/AudioHeap_Alloc.s,AudioHeap_Alloc,0x8018B6E8,0x16 +asm/non_matchings/code/audio_heap/AudioHeap_TestAlloc.s,AudioHeap_TestAlloc,0x8018B69C,0x13 +asm/non_matchings/code/audio_heap/Audio_Alloc.s,Audio_Alloc,0x8018B6E8,0x16 asm/non_matchings/code/audio_heap/AudioHeap_AllocPoolInit.s,AudioHeap_AllocPoolInit,0x8018B740,0xA -asm/non_matchings/code/audio_heap/func_8018B768.s,func_8018B768,0x8018B768,0x5 -asm/non_matchings/code/audio_heap/func_8018B77C.s,func_8018B77C,0x8018B77C,0xC -asm/non_matchings/code/audio_heap/func_8018B7AC.s,func_8018B7AC,0x8018B7AC,0x4 -asm/non_matchings/code/audio_heap/func_8018B7BC.s,func_8018B7BC,0x8018B7BC,0x50 +asm/non_matchings/code/audio_heap/AudioHeap_ClearPersistentCache.s,AudioHeap_ClearPersistentCache,0x8018B768,0x5 +asm/non_matchings/code/audio_heap/AudioHeap_ClearTemporaryCache.s,AudioHeap_ClearTemporaryCache,0x8018B77C,0xC +asm/non_matchings/code/audio_heap/AudioHeap_ResetPool.s,AudioHeap_ResetPool,0x8018B7AC,0x4 +asm/non_matchings/code/audio_heap/AudioHeap_PopCache.s,AudioHeap_PopCache,0x8018B7BC,0x50 asm/non_matchings/code/audio_heap/AudioHeap_InitMainPool.s,AudioHeap_InitMainPool,0x8018B8FC,0x18 -asm/non_matchings/code/audio_heap/func_8018B95C.s,func_8018B95C,0x8018B95C,0x21 -asm/non_matchings/code/audio_heap/func_8018B9E0.s,func_8018B9E0,0x8018B9E0,0x21 -asm/non_matchings/code/audio_heap/func_8018BA64.s,func_8018BA64,0x8018BA64,0x31 -asm/non_matchings/code/audio_heap/func_8018BB28.s,func_8018BB28,0x8018BB28,0x31 +asm/non_matchings/code/audio_heap/AudioHeap_InitSessionPool.s,AudioHeap_InitSessionPool,0x8018B95C,0x21 +asm/non_matchings/code/audio_heap/AudioHeap_InitCachePool.s,AudioHeap_InitCachePool,0x8018B9E0,0x21 +asm/non_matchings/code/audio_heap/AudioHeap_InitPersistentCache.s,AudioHeap_InitPersistentCache,0x8018BA64,0x31 +asm/non_matchings/code/audio_heap/AudioHeap_InitTemporaryCache.s,AudioHeap_InitTemporaryCache,0x8018BB28,0x31 asm/non_matchings/code/audio_heap/AudioHeap_AllocCached.s,AudioHeap_AllocCached,0x8018BBEC,0x1E5 asm/non_matchings/code/audio_heap/AudioHeap_SearchCaches.s,AudioHeap_SearchCaches,0x8018C380,0x16 -asm/non_matchings/code/audio_heap/func_8018C3D8.s,func_8018C3D8,0x8018C3D8,0x43 +asm/non_matchings/code/audio_heap/AudioHeap_SearchRegularCaches.s,AudioHeap_SearchRegularCaches,0x8018C3D8,0x43 asm/non_matchings/code/audio_heap/func_8018C4E4.s,func_8018C4E4,0x8018C4E4,0xF5 -asm/non_matchings/code/audio_heap/func_8018C8B8.s,func_8018C8B8,0x8018C8B8,0xC -asm/non_matchings/code/audio_heap/func_8018C8E8.s,func_8018C8E8,0x8018C8E8,0x15 -asm/non_matchings/code/audio_heap/func_8018C93C.s,func_8018C93C,0x8018C93C,0x16 -asm/non_matchings/code/audio_heap/func_8018C994.s,func_8018C994,0x8018C994,0x77 -asm/non_matchings/code/audio_heap/func_8018CB70.s,func_8018CB70,0x8018CB70,0x2 -asm/non_matchings/code/audio_heap/func_8018CB78.s,func_8018CB78,0x8018CB78,0x31 -asm/non_matchings/code/audio_heap/func_8018CC3C.s,func_8018CC3C,0x8018CC3C,0x1B +asm/non_matchings/code/audio_heap/AudioHeap_ClearFilter.s,AudioHeap_ClearFilter,0x8018C8B8,0xC +asm/non_matchings/code/audio_heap/AudioHeap_LoadLowPassFilter.s,AudioHeap_LoadLowPassFilter,0x8018C8E8,0x15 +asm/non_matchings/code/audio_heap/AudioHeap_LoadHighPassFilter.s,AudioHeap_LoadHighPassFilter,0x8018C93C,0x16 +asm/non_matchings/code/audio_heap/AudioHeap_LoadFilter.s,AudioHeap_LoadFilter,0x8018C994,0x77 +asm/non_matchings/code/audio_heap/AudioHeap_UpdateReverb.s,AudioHeap_UpdateReverb,0x8018CB70,0x2 +asm/non_matchings/code/audio_heap/AudioHeap_UpdateReverbs.s,AudioHeap_UpdateReverbs,0x8018CB78,0x31 +asm/non_matchings/code/audio_heap/AudioHeap_ClearAiBuffers.s,AudioHeap_ClearAiBuffers,0x8018CC3C,0x1B asm/non_matchings/code/audio_heap/AudioHeap_ResetStep.s,AudioHeap_ResetStep,0x8018CCA8,0xC1 -asm/non_matchings/code/audio_heap/func_8018CFAC.s,func_8018CFAC,0x8018CFAC,0x174 +asm/non_matchings/code/audio_heap/AudioHeap_Init.s,AudioHeap_Init,0x8018CFAC,0x174 asm/non_matchings/code/audio_heap/AudioHeap_SearchPermanentCache.s,AudioHeap_SearchPermanentCache,0x8018D57C,0x16 asm/non_matchings/code/audio_heap/AudioHeap_AllocPermanent.s,AudioHeap_AllocPermanent,0x8018D5D4,0x21 asm/non_matchings/code/audio_heap/AudioHeap_AllocSampleCache.s,AudioHeap_AllocSampleCache,0x8018D658,0x1C -asm/non_matchings/code/audio_heap/func_8018D6C8.s,func_8018D6C8,0x8018D6C8,0x26 -asm/non_matchings/code/audio_heap/func_8018D760.s,func_8018D760,0x8018D760,0xBC -asm/non_matchings/code/audio_heap/func_8018DA50.s,func_8018DA50,0x8018DA50,0x5D -asm/non_matchings/code/audio_heap/func_8018DBC4.s,func_8018DBC4,0x8018DBC4,0x3C -asm/non_matchings/code/audio_heap/func_8018DCB4.s,func_8018DCB4,0x8018DCB4,0x11 -asm/non_matchings/code/audio_heap/func_8018DCF8.s,func_8018DCF8,0x8018DCF8,0x28 -asm/non_matchings/code/audio_heap/func_8018DD98.s,func_8018DD98,0x8018DD98,0xF -asm/non_matchings/code/audio_heap/func_8018DDD4.s,func_8018DDD4,0x8018DDD4,0x54 -asm/non_matchings/code/audio_heap/func_8018DF24.s,func_8018DF24,0x8018DF24,0x2F -asm/non_matchings/code/audio_heap/func_8018DFE0.s,func_8018DFE0,0x8018DFE0,0xB +asm/non_matchings/code/audio_heap/AudioHeap_InitSampleCaches.s,AudioHeap_InitSampleCaches,0x8018D6C8,0x26 +asm/non_matchings/code/audio_heap/AudioHeap_AllocTemporarySampleCacheEntry.s,AudioHeap_AllocTemporarySampleCacheEntry,0x8018D760,0xBC +asm/non_matchings/code/audio_heap/AudioHeap_UnapplySampleCacheForFont.s,AudioHeap_UnapplySampleCacheForFont,0x8018DA50,0x5D +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSampleCacheEntry.s,AudioHeap_DiscardSampleCacheEntry,0x8018DBC4,0x3C +asm/non_matchings/code/audio_heap/AudioHeap_UnapplySampleCache.s,AudioHeap_UnapplySampleCache,0x8018DCB4,0x11 +asm/non_matchings/code/audio_heap/AudioHeap_AllocPersistentSampleCacheEntry.s,AudioHeap_AllocPersistentSampleCacheEntry,0x8018DCF8,0x28 +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSampleCacheForFont.s,AudioHeap_DiscardSampleCacheForFont,0x8018DD98,0xF +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSampleCaches.s,AudioHeap_DiscardSampleCaches,0x8018DDD4,0x54 +asm/non_matchings/code/audio_heap/AudioHeap_ChangeStorage.s,AudioHeap_ChangeStorage,0x8018DF24,0x2F +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSampleBank.s,AudioHeap_DiscardSampleBank,0x8018DFE0,0xB asm/non_matchings/code/audio_heap/AudioHeap_ApplySampleBankCache.s,AudioHeap_ApplySampleBankCache,0x8018E00C,0xC -asm/non_matchings/code/audio_heap/func_8018E03C.s,func_8018E03C,0x8018E03C,0x9B -asm/non_matchings/code/audio_heap/func_8018E2A8.s,func_8018E2A8,0x8018E2A8,0x27 -asm/non_matchings/code/audio_heap/func_8018E344.s,func_8018E344,0x8018E344,0x161 -asm/non_matchings/code/audio_heap/func_8018E8C8.s,func_8018E8C8,0x8018E8C8,0xA6 +asm/non_matchings/code/audio_heap/AudioHeap_ApplySampleBankCacheInternal.s,AudioHeap_ApplySampleBankCacheInternal,0x8018E03C,0x9B +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSampleBanks.s,AudioHeap_DiscardSampleBanks,0x8018E2A8,0x27 +asm/non_matchings/code/audio_heap/AudioHeap_SetReverbData.s,AudioHeap_SetReverbData,0x8018E344,0x161 +asm/non_matchings/code/audio_heap/AudioHeap_InitReverb.s,AudioHeap_InitReverb,0x8018E8C8,0xA6 asm/non_matchings/code/audio_load/AudioLoad_DecreaseSampleDmaTtls.s,AudioLoad_DecreaseSampleDmaTtls,0x8018EB60,0x3B asm/non_matchings/code/audio_load/AudioLoad_DmaSampleData.s,AudioLoad_DmaSampleData,0x8018EC4C,0xCF asm/non_matchings/code/audio_load/AudioLoad_InitSampleDmaBuffers.s,AudioLoad_InitSampleDmaBuffers,0x8018EF88,0xA6 @@ -3295,7 +3293,7 @@ asm/non_matchings/code/audio_seqplayer/AudioSeq_SequenceChannelDisable.s,AudioSe asm/non_matchings/code/audio_seqplayer/func_80197B14.s,func_80197B14,0x80197B14,0x3E asm/non_matchings/code/audio_seqplayer/func_80197C0C.s,func_80197C0C,0x80197C0C,0x20 asm/non_matchings/code/audio_seqplayer/func_80197C8C.s,func_80197C8C,0x80197C8C,0x26 -asm/non_matchings/code/audio_seqplayer/func_80197D24.s,func_80197D24,0x80197D24,0xA +asm/non_matchings/code/audio_seqplayer/AudioSeq_SequencePlayerDisableAsFinished.s,AudioSeq_SequencePlayerDisableAsFinished,0x80197D24,0xA asm/non_matchings/code/audio_seqplayer/AudioSeq_SequencePlayerDisable.s,AudioSeq_SequencePlayerDisable,0x80197D4C,0x2F asm/non_matchings/code/audio_seqplayer/AudioSeq_AudioListPushBack.s,AudioSeq_AudioListPushBack,0x80197E08,0x10 asm/non_matchings/code/audio_seqplayer/AudioSeq_AudioListPopBack.s,AudioSeq_AudioListPopBack,0x80197E48,0x10 @@ -3318,9 +3316,9 @@ asm/non_matchings/code/audio_seqplayer/func_8019A0BC.s,func_8019A0BC,0x8019A0BC, asm/non_matchings/code/audio_seqplayer/func_8019AA3C.s,func_8019AA3C,0x8019AA3C,0x2D asm/non_matchings/code/audio_seqplayer/func_8019AAF0.s,func_8019AAF0,0x8019AAF0,0x14 asm/non_matchings/code/audio_seqplayer/AudioSeq_ResetSequencePlayer.s,AudioSeq_ResetSequencePlayer,0x8019AB40,0x34 -asm/non_matchings/code/audio_seqplayer/func_8019AC10.s,func_8019AC10,0x8019AC10,0x37 +asm/non_matchings/code/audio_seqplayer/AudioSeq_InitSequencePlayerChannels.s,AudioSeq_InitSequencePlayerChannels,0x8019AC10,0x37 asm/non_matchings/code/audio_seqplayer/func_8019ACEC.s,func_8019ACEC,0x8019ACEC,0x34 -asm/non_matchings/code/audio_seqplayer/func_8019ADBC.s,func_8019ADBC,0x8019ADBC,0x21 +asm/non_matchings/code/audio_seqplayer/AudioSeq_InitSequencePlayers.s,AudioSeq_InitSequencePlayers,0x8019ADBC,0x21 asm/non_matchings/code/code_8019AE40/func_8019AE40.s,func_8019AE40,0x8019AE40,0x1C asm/non_matchings/code/code_8019AEC0/func_8019AEC0.s,func_8019AEC0,0x8019AEC0,0x10 asm/non_matchings/code/code_8019AF00/func_8019AF00.s,func_8019AF00,0x8019AF00,0x16