Files
SpaghettiKart/src/audio/heap.c
T
Tyler McGavran 86c86c8bcd Lots of matches in the audio code (#417)
* Lots of audio matches

Fully matched heap.c, lots of load.c and some stuff in seqplayer.c

Matched heap.c's BSS segement and moved some BSS stuff out of
 load.c into data.c, since that where it appears to belong
 according to SM64.

Signed-off-by: Taggerung <tyler.taggerung@email.com>
2023-09-13 22:36:27 -06:00

755 lines
29 KiB
C

#include <ultra64.h>
#include <macros.h>
#include "audio/data.h"
#include "audio/effects.h"
#include "audio/heap.h"
#include "audio/load.h"
#include "audio/synthesis.h"
#include "audio/playback.h"
#include "audio/seqplayer.h"
s16 gVolume;
s8 gUseReverb;
s8 gNumSynthesisReverbs;
struct NoteSubEu *gNoteSubsEu;
struct SoundAllocPool gAudioSessionPool;
struct SoundAllocPool gAudioInitPool;
struct SoundAllocPool gNotesAndBuffersPool;
u8 sAudioHeapPad[0x20]; // probably two unused pools
struct SoundAllocPool gSeqAndBankPool;
struct SoundAllocPool gPersistentCommonPool;
struct SoundAllocPool gTemporaryCommonPool;
struct SoundMultiPool gSeqLoadedPool;
struct SoundMultiPool gBankLoadedPool;
struct SoundMultiPool gUnusedLoadedPool;
struct Unk1Pool gUnkPool1;
struct PoolSplit sSessionPoolSplit;
struct PoolSplit2 sSeqAndBankPoolSplit;
struct PoolSplit sPersistentCommonPoolSplit;
struct PoolSplit sTemporaryCommonPoolSplit;
u8 gUnkLoadStatus[0x40];
u8 gBankLoadStatus[0x40];
u8 gSeqLoadStatus[0x100];
volatile u8 gAudioResetStatus;
u8 gAudioResetPresetIdToLoad;
s32 gAudioResetFadeOutFramesLeft;
u8 gAudioUnusedBuffer[0x1000];
struct Note *gNotes;
/**
* Given that (almost) all of these are format strings, it is highly likely
* that they are meant to be used in some sort of printf variant. But I don't
* care to try and figure out which function gets which string(s)
* So I've place them all here instead.
**/
char heapAudioString00[] = "Warning:Kill Note %x \n";
char heapAudioString01[] = "Kill Voice %d (ID %d) %d\n";
char heapAudioString02[] = "Warning: Running Sequence's data disappear!\n";
char heapAudioString03[] = "Audio:Memory:Heap OverFlow : Not Allocate %d!\n";
char heapAudioString04[] = "Audio:Memory:DataHeap Not Allocate \n";
char heapAudioString05[] = "StayHeap Not Allocate %d\n";
char heapAudioString06[] = "AutoHeap Not Allocate %d\n";
char heapAudioString07[] = "Status ID0 : %d ID1 : %d\n";
char heapAudioString08[] = "id 0 is Stopping\n";
char heapAudioString09[] = "id 0 is Stop\n";
char heapAudioString10[] = "id 1 is Stopping\n";
char heapAudioString11[] = "id 1 is Stop\n";
char heapAudioString12[] = "WARNING: NO FREE AUTOSEQ AREA.\n";
char heapAudioString13[] = "WARNING: NO STOP AUTO AREA.\n";
char heapAudioString14[] = " AND TRY FORCE TO STOP SIDE \n";
char heapAudioString15[] = "Check ID0 (seq ID %d) Useing ...\n";
char heapAudioString16[] = "Check ID1 (seq ID %d) Useing ...\n";
char heapAudioString17[] = "No Free Seq area.\n";
char heapAudioString18[] = "CH %d: ID %d\n";
char heapAudioString19[] = "TWO SIDES ARE LOADING... ALLOC CANCELED.\n";
char heapAudioString20[] = "WARNING: Before Area Overlaid After.";
char heapAudioString21[] = "WARNING: After Area Overlaid Before.";
char heapAudioString22[] = "MEMORY:SzHeapAlloc ERROR: sza->side %d\n";
char heapAudioString23[] = "Audio:MEMORY:SzHeap Overflow error. (%d bytes)\n";
char heapAudioString24[] = "Auto Heap Unhit for ID %d\n";
char heapAudioString25[] = "Heap Reconstruct Start %x\n";
char heapAudioString26[] = "AHPBASE %x\n";
char heapAudioString27[] = "AHPCUR %x\n";
char heapAudioString28[] = "HeapTop %x\n";
char heapAudioString29[] = "SynoutRate %d / %d \n";
char heapAudioString30[] = "FXSIZE %d\n";
char heapAudioString31[] = "FXCOMP %d\n";
char heapAudioString32[] = "FXDOWN %d\n";
char heapAudioString33[] = "WaveCacheLen: %d\n";
char heapAudioString34[] = "SpecChange Finished\n";
char heapAudioString35[] = "Fbank Seq %x\n";
char heapAudioString36[] = "Already Load Type %d,ID %d\n";
char heapAudioString37[] = "Warning:Emem Over,not alloc %d\n";
char heapAudioString38[] = "Write %d\n";
extern u8 gUnkLoadStatus[];
void reset_bank_and_seq_load_status(void) {
s32 i;
for (i = 0; i < 64; i++) {
if(gBankLoadStatus[i] != 5) {
gBankLoadStatus[i] = 0;
}
}
for (i = 0; i < 64; i++) {
if(gUnkLoadStatus[i] != 5) {
gUnkLoadStatus[i] = 0;
}
}
for (i = 0; i < 256; i++) {
if (gSeqLoadStatus[i] != 5) {
gSeqLoadStatus[i] = 0;
}
}
}
void discard_bank(s32 bankId) {
s32 i;
for (i = 0; i < gMaxSimultaneousNotes; i++) {
struct Note *note = &gNotes[i];
if (note->noteSubEu.bankId == bankId) {
// (These prints are unclear. Arguments are picked semi-randomly.)
// eu_stubbed_printf_1("Warning:Kill Note %x \n", i);
if (note->priority >= NOTE_PRIORITY_MIN) {
// eu_stubbed_printf_3("Kill Voice %d (ID %d) %d\n", note->waveId, bankId, note->priority);
// eu_stubbed_printf_0("Warning: Running Sequence's data disappear!\n");
note->parentLayer->enabled = FALSE; // is 0x48, should be 0x44
note->parentLayer->finished = TRUE;
}
note_disable(note);
audio_list_remove(&note->listItem);
audio_list_push_back(&gNoteFreeLists.disabled, &note->listItem);
}
}
}
void discard_sequence(s32 seqId) {
s32 i;
for (i = 0; i < SEQUENCE_PLAYERS; i++) {
if (gSequencePlayers[i].enabled && gSequencePlayers[i].seqId == seqId) {
sequence_player_disable(&gSequencePlayers[i]);
}
}
}
void *soundAlloc(struct SoundAllocPool *pool, u32 size) {
u8 *start;
u8 *pos;
u32 alignedSize = ALIGN16(size);
start = pool->cur;
if (start + alignedSize <= pool->start + pool->size) {
pool->cur += alignedSize;
for (pos = start; pos < pool->cur; pos++) {
*pos = 0;
}
} else {
// eu_stubbed_printf_1("Heap OverFlow : Not Allocate %d!\n", size);
return NULL;
}
pool->numAllocatedEntries++;
return start;
}
void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size) {
pool->cur = pool->start = (u8 *) ALIGN16((uintptr_t) memAddr);
pool->size = size;
pool->numAllocatedEntries = 0;
}
void persistent_pool_clear(struct PersistentPool *persistent) {
persistent->pool.numAllocatedEntries = 0;
persistent->pool.cur = persistent->pool.start;
persistent->numEntries = 0;
}
void temporary_pool_clear(struct TemporaryPool *temporary) {
temporary->pool.numAllocatedEntries = 0;
temporary->pool.cur = temporary->pool.start;
temporary->nextSide = 0;
temporary->entries[0].ptr = temporary->pool.start;
temporary->entries[1].ptr = temporary->pool.start + temporary->pool.size;
temporary->entries[0].id = -1; // should be at 1e not 1c
temporary->entries[1].id = -1;
}
void func_800B90E0(struct SoundAllocPool *pool) {
pool->numAllocatedEntries = 0;
pool->cur = pool->start;
}
// inspired by sound_init_main_pools in sm64
void func_800B90F0(s32 arg0) {
sound_alloc_pool_init(&gAudioInitPool, &D_803B71B0, arg0);
sound_alloc_pool_init(&gAudioSessionPool, D_803B71B0 + arg0, D_800EA5D0 - arg0);
}
// inspired by session_pools_init in sm64
void func_800B914C(struct PoolSplit *arg0) {
gAudioSessionPool.cur = gAudioSessionPool.start;
sound_alloc_pool_init(&gNotesAndBuffersPool, soundAlloc(&gAudioSessionPool, arg0->wantSeq), arg0->wantSeq);
sound_alloc_pool_init(&gSeqAndBankPool, soundAlloc(&gAudioSessionPool, arg0->wantCustom), arg0->wantCustom);
}
void seq_and_bank_pool_init(struct PoolSplit2 *a) {
gSeqAndBankPool.cur = gSeqAndBankPool.start;
sound_alloc_pool_init(&gPersistentCommonPool, soundAlloc(&gSeqAndBankPool, a->wantPersistent), a->wantPersistent);
sound_alloc_pool_init(&gTemporaryCommonPool, soundAlloc(&gSeqAndBankPool, a->wantTemporary), a->wantTemporary);
}
void persistent_pools_init(struct PoolSplit *a) {
gPersistentCommonPool.cur = gPersistentCommonPool.start;
sound_alloc_pool_init(&gSeqLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantSeq), a->wantSeq);
sound_alloc_pool_init(&gBankLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantBank), a->wantBank);
sound_alloc_pool_init(&gUnusedLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantUnused), a->wantUnused);
persistent_pool_clear(&gSeqLoadedPool.persistent);
persistent_pool_clear(&gBankLoadedPool.persistent);
persistent_pool_clear(&gUnusedLoadedPool.persistent);
}
void temporary_pools_init(struct PoolSplit *a) {
gTemporaryCommonPool.cur = gTemporaryCommonPool.start;
sound_alloc_pool_init(&gSeqLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantSeq), a->wantSeq);
sound_alloc_pool_init(&gBankLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantBank), a->wantBank);
sound_alloc_pool_init(&gUnusedLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantUnused), a->wantUnused);
temporary_pool_clear(&gSeqLoadedPool.temporary);
temporary_pool_clear(&gBankLoadedPool.temporary);
temporary_pool_clear(&gUnusedLoadedPool.temporary);
}
void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id) {
struct TemporaryPool *tp;
struct SoundAllocPool *pool;
void *ret;
u16 UNUSED _firstVal;
u16 UNUSED _secondVal;
u16 firstVal;
u16 secondVal;
s32 var_v1_2;
u8 *table;
u8 isSound;
if (arg3 == 0) {
tp = &arg0->temporary;
if (arg0 == &gSeqLoadedPool) {
table = gSeqLoadStatus; isSound = 0;
} else {
// wtf?
firstVal += 0;
if (arg0 == &gBankLoadedPool) {
isSound = 1; table = gBankLoadStatus;
} else if (arg0 == &gUnusedLoadedPool) {
table = gUnkLoadStatus; isSound = 2;
}
}
if (tp->entries[0].id == -1) {
firstVal = 0;
} else {
firstVal = table[tp->entries[0].id];
}
if (tp->entries[1].id == -1) {
secondVal = 0;
} else {
secondVal = table[tp->entries[1].id];
}
if (isSound == 1) {
if (firstVal == 4) {
for (var_v1_2 = 0; var_v1_2 < gMaxSimultaneousNotes; var_v1_2++) {
if (gNotes[var_v1_2].noteSubEu.bankId == tp->entries[0].id && gNotes[var_v1_2].noteSubEu.enabled) {
break;
}
}
if (var_v1_2 == gMaxSimultaneousNotes) {
if (gBankLoadStatus[tp->entries[0].id] != SOUND_LOAD_STATUS_5) {
gBankLoadStatus[tp->entries[0].id] = SOUND_LOAD_STATUS_DISCARDABLE;
}
firstVal = SOUND_LOAD_STATUS_DISCARDABLE;
}
}
if (secondVal == 4) {
for (var_v1_2 = 0; var_v1_2 < gMaxSimultaneousNotes; var_v1_2++) {
if (gNotes[var_v1_2].noteSubEu.bankId == tp->entries[1].id && gNotes[var_v1_2].noteSubEu.enabled) {
break;
}
}
if (var_v1_2 == gMaxSimultaneousNotes) {
if (gBankLoadStatus[tp->entries[1].id] != SOUND_LOAD_STATUS_5) {
gBankLoadStatus[tp->entries[1].id] = SOUND_LOAD_STATUS_DISCARDABLE;
}
secondVal = SOUND_LOAD_STATUS_DISCARDABLE;
}
}
}
if (firstVal == 0) {
tp->nextSide = 0;
} else if (secondVal == 0) {
tp->nextSide = 1;
} else {
if ((firstVal == 3) && (secondVal == 3)) {
// ?
} else if (firstVal == 3) {
tp->nextSide = 0;
} else if (secondVal == 3) {
tp->nextSide = 1;
} else {
if (isSound == 0) {
if (firstVal == SOUND_LOAD_STATUS_COMPLETE) {
for (var_v1_2 = 0; var_v1_2 < SEQUENCE_PLAYERS; var_v1_2++) {
if (gSequencePlayers[var_v1_2].enabled && gSequencePlayers[var_v1_2].seqId == tp->entries[0].id) {
break;
}
}
if (var_v1_2 == SEQUENCE_PLAYERS) {
tp->nextSide = 0;
goto out;
}
}
if (secondVal == SOUND_LOAD_STATUS_COMPLETE) {
for (var_v1_2 = 0; var_v1_2 < SEQUENCE_PLAYERS; var_v1_2++) {
if (gSequencePlayers[var_v1_2].enabled && gSequencePlayers[var_v1_2].seqId == tp->entries[1].id) {
break;
}
}
if (var_v1_2 == SEQUENCE_PLAYERS) {
tp->nextSide = 1;
goto out;
}
}
} else if (isSound == 1) {
if (firstVal == SOUND_LOAD_STATUS_COMPLETE) {
for (var_v1_2 = 0; var_v1_2 < gMaxSimultaneousNotes; var_v1_2++) {
if (gNotes[var_v1_2].noteSubEu.bankId == tp->entries[0].id && gNotes[var_v1_2].noteSubEu.enabled) {
break;
}
}
if (var_v1_2 == gMaxSimultaneousNotes) {
tp->nextSide = 0;
goto out;
}
}
if (secondVal == SOUND_LOAD_STATUS_COMPLETE) {
for (var_v1_2 = 0; var_v1_2 < gMaxSimultaneousNotes; var_v1_2++) {
if (gNotes[var_v1_2].noteSubEu.bankId == tp->entries[1].id && gNotes[var_v1_2].noteSubEu.enabled) {
break;
}
}
if (var_v1_2 == gMaxSimultaneousNotes) {
tp->nextSide = 1;
goto out;
}
}
}
if (tp->nextSide == 0) {
if (firstVal == SOUND_LOAD_STATUS_IN_PROGRESS) {
if (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
tp->nextSide = 1;
goto out;
}
} else {
goto out;
}
} else {
if (secondVal == SOUND_LOAD_STATUS_IN_PROGRESS) {
if (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
tp->nextSide = 0;
goto out;
}
} else {
goto out;
}
}
return NULL;
out:;
}
}
pool = &arg0->temporary.pool;
if (tp->entries[tp->nextSide].id != (s8)-1) {
table[tp->entries[tp->nextSide].id] = SOUND_LOAD_STATUS_NOT_LOADED;
if (isSound == TRUE) {
discard_bank(tp->entries[tp->nextSide].id);
}
}
switch (tp->nextSide) {
case 0:
tp->entries[0].ptr = pool->start;
tp->entries[0].id = (s16) id;
tp->entries[0].size = (u32) size;
pool->cur = pool->start + size;
if (tp->entries[1].ptr < pool->cur) {
table[tp->entries[1].id] = 0;
switch (isSound) { /* irregular */
case 0:
discard_sequence((s32) tp->entries[1].id);
break;
case 1:
discard_bank((s32) tp->entries[1].id);
break;
}
tp->entries[1].id = -1;
tp->entries[1].ptr = pool->start + pool->size;
}
ret = tp->entries[0].ptr;
break;
case 1:
tp->entries[1].ptr = pool->start + pool->size - size - 0x10;
tp->entries[1].id = (s16) id;
tp->entries[1].size = (u32) size;
if ((u32) tp->entries[1].ptr < (u32) pool->cur) {
table[tp->entries[0].id] = 0;
switch (isSound) { /* switch 1; irregular */
case 0: /* switch 1 */
discard_sequence((s32) tp->entries[0].id);
break;
case 1: /* switch 1 */
discard_bank((s32) tp->entries[0].id);
break;
}
tp->entries[0].id = -1;
pool->cur = pool->start;
}
ret = tp->entries[1].ptr;
break;
default:
return NULL;
}
tp->nextSide ^= 1;
return ret;
}
ret = soundAlloc(&arg0->persistent.pool, arg1 * size);
arg0->persistent.entries[arg0->persistent.numEntries].ptr = ret;
if (ret == NULL) {
switch (arg3) {
case 2:
return alloc_bank_or_seq(arg0, arg1, size, 0, id);
case 1:
case 0:
return NULL;
}
}
arg0->persistent.entries[arg0->persistent.numEntries].id = (s16) id;
arg0->persistent.entries[arg0->persistent.numEntries].size = (u32) size;
return arg0->persistent.entries[arg0->persistent.numEntries++].ptr;
}
void *get_bank_or_seq(s32 poolIdx, s32 arg1, s32 id) {
void *ret;
ret = unk_pool1_lookup(poolIdx, id);
if (ret != NULL) {
return ret;
}
return get_bank_or_seq_inner(poolIdx, arg1, id);
}
void *get_bank_or_seq_inner(s32 poolIdx, s32 arg1, s32 bankId) {
u32 i;
struct SoundMultiPool* loadedPool;
struct TemporaryPool* temporary;
struct PersistentPool* persistent;
switch (poolIdx) {
case 0:
loadedPool = &gSeqLoadedPool;
break;
case 1:
loadedPool = &gBankLoadedPool;
break;
case 2:
loadedPool = &gUnusedLoadedPool;
break;
}
temporary = &loadedPool->temporary;
if (arg1 == 0) {
if (temporary->entries[0].id == bankId) {
temporary->nextSide = 1;
return temporary->entries[0].ptr;
} else if (temporary->entries[1].id == bankId) {
temporary->nextSide = 0;
return temporary->entries[1].ptr;
} else {
return NULL;
}
}
persistent = &loadedPool->persistent;
for (i = 0; i < persistent->numEntries; i++) {
if (persistent->entries[i].id == bankId) {
return persistent->entries[i].ptr;
}
}
if (arg1 == 2) {
return get_bank_or_seq(poolIdx, 0, bankId);
}
return NULL;
}
void func_800B9BE4(f32 arg0, f32 arg1, u16 *arg2) {
s32 i;
f32 tmp[16];
tmp[0] = arg1 * 262159.0f;
tmp[8] = arg0 * 262159.0f;
tmp[1] = (arg1 * arg0) * 262159.0f;
tmp[9] = ((arg0 * arg0) + arg1) * 262159.0f;
for (i = 2; i < 8; i++) {
//! @bug they probably meant to store the value to tmp[i] and tmp[8 + i]
arg2[i] = arg1 * tmp[i - 2] + arg0 * tmp[i - 1];
arg2[8 + i] = arg1 * tmp[6 + i] + arg0 * tmp[7 + i];
}
for (i = 0; i < 16; i++) {
arg2[i] = tmp[i];
}
}
void decrease_reverb_gain(void) {
s32 i;
for (i = 0; i < gNumSynthesisReverbs; i++) {
gSynthesisReverbs[i].reverbGain -= gSynthesisReverbs[i].reverbGain / 4;
}
}
s32 audio_shut_down_and_reset_step(void) {
s32 i;
s32 j;
switch (gAudioResetStatus) {
case 5:
for (i = 0; i < SEQUENCE_PLAYERS; i++) {
sequence_player_disable(&gSequencePlayers[i]);
}
gAudioResetFadeOutFramesLeft = 4;
gAudioResetStatus--;
break;
case 4:
if (gAudioResetFadeOutFramesLeft != 0) {
gAudioResetFadeOutFramesLeft--;
decrease_reverb_gain();
} else {
for (i = 0; i < gMaxSimultaneousNotes; i++) {
if (gNotes[i].noteSubEu.enabled && gNotes[i].adsr.state != ADSR_STATE_DISABLED) {
gNotes[i].adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv;
gNotes[i].adsr.action |= ADSR_ACTION_RELEASE;
}
}
gAudioResetFadeOutFramesLeft = 0x00000010;
gAudioResetStatus--;
}
break;
case 3:
if (gAudioResetFadeOutFramesLeft != 0) {
gAudioResetFadeOutFramesLeft--;
decrease_reverb_gain();
} else {
for (i = 0; i < NUMAIBUFFERS; i++) {
for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) {
gAiBuffers[i][j] = 0;
}
}
gAudioResetFadeOutFramesLeft = 4;
gAudioResetStatus--;
}
break;
case 2:
if (gAudioResetFadeOutFramesLeft != 0) {
gAudioResetFadeOutFramesLeft--;
} else {
gAudioResetStatus--;
}
break;
case 1:
audio_reset_session();
gAudioResetStatus = 0;
break;
}
if (gAudioResetStatus < 3) {
return 0;
}
return 1;
}
void audio_reset_session(void) {
s32 var_s1;
s32 var_s5;
s32 temp;
u32 totalMem;
u32 temporaryMem;
u32 persistentMem;
s16 *mem;
struct SynthesisReverb *reverb;
struct ReverbSettingsEU *reverbSettings;
struct AudioSessionSettingsEU *temp_s6 = &gAudioSessionPresets[gAudioResetPresetIdToLoad];
gSampleDmaNumListItems = 0;
gAudioBufferParameters.frequency = temp_s6->frequency;
gAudioBufferParameters.aiFrequency = osAiSetFrequency(gAudioBufferParameters.frequency);
gAudioBufferParameters.samplesPerFrameTarget = ALIGN16(gAudioBufferParameters.frequency / gRefreshRate);
gAudioBufferParameters.minAiBufferLength = gAudioBufferParameters.samplesPerFrameTarget - 0x10;
gAudioBufferParameters.maxAiBufferLength = gAudioBufferParameters.samplesPerFrameTarget + 0x10;
gAudioBufferParameters.updatesPerFrame = ((gAudioBufferParameters.samplesPerFrameTarget + 0x10) / 192) + 1;
gAudioBufferParameters.samplesPerUpdate = (gAudioBufferParameters.samplesPerFrameTarget / gAudioBufferParameters.updatesPerFrame) & ~0x0007;
gAudioBufferParameters.samplesPerUpdateMax = gAudioBufferParameters.samplesPerUpdate + 8;
gAudioBufferParameters.samplesPerUpdateMin = gAudioBufferParameters.samplesPerUpdate - 8;
gAudioBufferParameters.resampleRate = 32000.0f / ((f32)(s32)gAudioBufferParameters.frequency);
gAudioBufferParameters.unkUpdatesPerFrameScaled = 0.001171875f / gAudioBufferParameters.updatesPerFrame;
gAudioBufferParameters.updatesPerFrameInv = 1.0f / gAudioBufferParameters.updatesPerFrame;
gMaxSimultaneousNotes = temp_s6->maxSimultaneousNotes;
gVolume = temp_s6->volume;
gTempoInternalToExternal = (u32) (((gAudioBufferParameters.updatesPerFrame * 2880000.0f) / gTatumsPerBeat) / D_803B7178);
gAudioBufferParameters.presetUnk4 = temp_s6->unk1;
gAudioBufferParameters.samplesPerFrameTarget *= gAudioBufferParameters.presetUnk4;
gAudioBufferParameters.maxAiBufferLength *= gAudioBufferParameters.presetUnk4;
gAudioBufferParameters.minAiBufferLength *= gAudioBufferParameters.presetUnk4;
gAudioBufferParameters.updatesPerFrame *= gAudioBufferParameters.presetUnk4;
gMaxAudioCmds = (gMaxSimultaneousNotes * 0x14 * gAudioBufferParameters.updatesPerFrame) + (temp_s6->numReverbs * 0x20) + 0x1E0;
persistentMem = temp_s6->persistentSeqMem + temp_s6->persistentBankMem + temp_s6->unk_18;
temporaryMem = temp_s6->temporarySeqMem + temp_s6->temporaryBankMem + temp_s6->unk_24;
totalMem = persistentMem + temporaryMem;
temp = (gAudioSessionPool.size - totalMem) - 0x100;
sSessionPoolSplit.wantSeq = temp;
sSessionPoolSplit.wantCustom = totalMem;
func_800B914C(&sSessionPoolSplit);
sSeqAndBankPoolSplit.wantPersistent = persistentMem;
sSeqAndBankPoolSplit.wantTemporary = temporaryMem;
seq_and_bank_pool_init(&sSeqAndBankPoolSplit);
sPersistentCommonPoolSplit.wantSeq = temp_s6->persistentSeqMem;
sPersistentCommonPoolSplit.wantBank = temp_s6->persistentBankMem;
sPersistentCommonPoolSplit.wantUnused = temp_s6->unk_18;
persistent_pools_init(&sPersistentCommonPoolSplit);
sTemporaryCommonPoolSplit.wantSeq = temp_s6->temporarySeqMem;
sTemporaryCommonPoolSplit.wantBank = temp_s6->temporaryBankMem;
sTemporaryCommonPoolSplit.wantUnused = temp_s6->unk_24;
temporary_pools_init(&sTemporaryCommonPoolSplit);
reset_bank_and_seq_load_status();
gNotes = soundAlloc(&gNotesAndBuffersPool, gMaxSimultaneousNotes * sizeof(struct Note));
note_init_all();
init_note_free_list();
gNoteSubsEu = soundAlloc(&gNotesAndBuffersPool, gAudioBufferParameters.updatesPerFrame * gMaxSimultaneousNotes * 0x10);
for (var_s5 = 0; var_s5 != 2; var_s5++) {
gAudioCmdBuffers[var_s5] = soundAlloc(&gNotesAndBuffersPool, gMaxAudioCmds * sizeof(u64));
}
for (var_s5 = 0; var_s5 < 4; var_s5++) {
gSynthesisReverbs[var_s5].useReverb = 0;
}
gNumSynthesisReverbs = temp_s6->numReverbs;
for (var_s5 = 0; var_s5 < gNumSynthesisReverbs; var_s5++) {
reverb = &gSynthesisReverbs[var_s5];
reverbSettings = &temp_s6->reverbSettings[var_s5];
reverb->windowSize = reverbSettings->windowSize * 64;
reverb->downsampleRate = reverbSettings->downsampleRate;
reverb->reverbGain = reverbSettings->gain;
reverb->useReverb = 8;
reverb->ringBuffer.left = soundAlloc(&gNotesAndBuffersPool, reverb->windowSize * 2);
reverb->ringBuffer.right = soundAlloc(&gNotesAndBuffersPool, reverb->windowSize * 2);
reverb->nextRingBufferPos = 0;
reverb->unkC = 0;
reverb->curFrame = 0;
reverb->bufSizePerChannel = reverb->windowSize;
reverb->framesLeftToIgnore = 2;
if (reverb->downsampleRate != 1) {
reverb->resampleFlags = 1;
reverb->resampleRate = 0x8000 / reverb->downsampleRate;
reverb->resampleStateLeft = soundAlloc(&gNotesAndBuffersPool, 0x00000020U);
reverb->resampleStateRight = soundAlloc(&gNotesAndBuffersPool, 0x00000020U);
reverb->unk24 = soundAlloc(&gNotesAndBuffersPool, 0x00000020U);
reverb->unk28 = soundAlloc(&gNotesAndBuffersPool, 0x00000020U);
for (var_s1 = 0; var_s1 < gAudioBufferParameters.updatesPerFrame; var_s1++) {
mem = soundAlloc(&gNotesAndBuffersPool, 0x00000300U);
reverb->items[0][var_s1].toDownsampleLeft = mem;
reverb->items[0][var_s1].toDownsampleRight = mem + (DEFAULT_LEN_1CH / sizeof(s16));
mem = soundAlloc(&gNotesAndBuffersPool, 0x00000300U);
reverb->items[1][var_s1].toDownsampleLeft = mem;
reverb->items[1][var_s1].toDownsampleRight = mem + (DEFAULT_LEN_1CH / sizeof(s16));
}
}
}
func_800BB030(gMaxSimultaneousNotes);
osWritebackDCacheAll();
}
void *unk_pool1_lookup(s32 poolIdx, s32 id) {
s32 i;
for (i = 0; i < gUnkPool1.pool.numAllocatedEntries; i++) {
if (gUnkPool1.entries[i].poolIndex == poolIdx && gUnkPool1.entries[i].id == id) {
return gUnkPool1.entries[i].ptr;
}
}
return NULL;
}
// SM64 does not appear to have a function
// comparable to this one, not a clue what
// this one is doing.
void func_800BA8B0(s32 poolIdx, s32 id) {
ALSeqFile *sp3C;
s32 temp_a2;
u32 temp_a1;
u8 *var_a3;
u8 *temp_v0;
s32 pad;
switch (poolIdx) { /* irregular */
case 0:
sp3C = gSeqFileHeader;
break;
case 1:
sp3C = gAlCtlHeader;
break;
case 2:
sp3C = gAlTbl;
break;
}
if (sp3C->seqArray[id].len == 0) {
id = sp3C->seqArray[id].offset;
}
if (unk_pool1_lookup(poolIdx, id) == NULL) {
temp_a2 = gUnkPool1.pool.numAllocatedEntries;
temp_a1 = sp3C->seqArray[id].len;
var_a3 = sp3C->seqArray[id].offset;
if (poolIdx == 1) {
var_a3 += 0x10;
}
gUnkPool1.entries[temp_a2].ptr = soundAlloc(&gUnkPool1.pool, temp_a1);
if (gUnkPool1.entries[temp_a2].ptr != NULL) {
audio_dma_copy_immediate(var_a3, gUnkPool1.entries[temp_a2].ptr, temp_a1);
gUnkPool1.entries[temp_a2].poolIndex = poolIdx;
gUnkPool1.entries[temp_a2].id = id;
gUnkPool1.entries[temp_a2].size = temp_a1;
switch (poolIdx) { /* switch 1; irregular */
case 0: /* switch 1 */
if (gSeqLoadStatus[id] != 5) {
gSeqLoadStatus[id] = 5;
}
break;
case 1: /* switch 1 */
gCtlEntries[id].instruments = (struct Instrument **) (gUnkPool1.entries[temp_a2].ptr + 4);
func_800BB584(id);
if (gBankLoadStatus[id] != 5) {
gBankLoadStatus[id] = 5;
}
break;
case 2: /* switch 1 */
break;
}
}
}
}