Files
SpaghettiKart/src/audio/heap.c
T
Tyler McGavran 782ed71f61 Massive data relocation (#295)
Mostly relocating rodata from data/* files to the appropriate
 asm/nonmatching/* files, although there is some plain data
 relocating to be found in here too.

Big change to note is the addition of the code_802AAA70.c file,
 split from memory.c. Based on some padding in the ro/data for
 memory it seems clear that a split is needed, although it is
 not clear that exact spot chosen for the split is correct.
 Still, it gets the file padding for the ro/data and text segments
 correct so it can't be too wrong.

Also included is an update to the asm_processor tool to support
 the .hword directive. I made a PR to the main repo of that
 project with an identical change and it was accepted.

Signed-off-by: Taggerung <tyler.taggerung@gmail.com>
2023-03-29 18:52:15 -06:00

1043 lines
35 KiB
C

#include <ultra64.h>
#include <macros.h>
#include "audio/heap.h"
#include "audio/load.h"
#include "audio/synthesis.h"
#include "audio/playback.h"
#include "audio/seqplayer.h"
extern struct SoundAllocPool gNotesAndBuffersPool;
/**
* 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";
#ifdef MIPS_TO_C
//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307
extern u8 D_803B0380;
extern u8 gBankLoadStatus;
extern ? gSeqLoadStatus;
extern u8 D_803B0500;
void func_800B8DE0(void) {
? *temp_v1_3;
u8 *temp_v1;
u8 *temp_v1_2;
u8 *phi_v1;
u8 *phi_v1_2;
? *phi_v1_3;
phi_v1 = &gBankLoadStatus;
do {
if (*phi_v1 != 5) {
*phi_v1 = 0;
}
temp_v1 = phi_v1 + 1;
phi_v1 = temp_v1;
} while (temp_v1 < &gSeqLoadStatus);
phi_v1_2 = &D_803B0380;
do {
if (*phi_v1_2 != 5) {
*phi_v1_2 = 0;
}
temp_v1_2 = phi_v1_2 + 1;
phi_v1_2 = temp_v1_2;
} while (temp_v1_2 < &gBankLoadStatus);
phi_v1_3 = &gSeqLoadStatus;
do {
if (phi_v1_3->unk0 != 5) {
phi_v1_3->unk0 = 0;
}
if (phi_v1_3->unk1 != 5) {
phi_v1_3->unk1 = 0;
}
if (phi_v1_3->unk2 != 5) {
phi_v1_3->unk2 = 0;
}
if (phi_v1_3->unk3 != 5) {
phi_v1_3->unk3 = 0;
}
temp_v1_3 = phi_v1_3 + 4;
phi_v1_3 = temp_v1_3;
} while (temp_v1_3 != &D_803B0500);
}
#else
GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B8DE0.s")
#endif
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;
}
extern s32 D_800EA5D0;
extern u8 D_803B71B0[];
// 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(&gLeftVolRampings, D_803B71B0 + arg0, D_800EA5D0 - arg0);
}
// inspired by session_pools_init in sm64
void func_800B914C(struct PoolSplit *arg0) {
gLeftVolRampings.cur = gLeftVolRampings.start;
sound_alloc_pool_init(&gNotesAndBuffersPool, soundAlloc(&gLeftVolRampings, arg0->wantSeq), arg0->wantSeq);
sound_alloc_pool_init(&gSeqAndBankPool, soundAlloc(&gLeftVolRampings, 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);
}
#ifdef MIPS_TO_C
//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c
? discard_bank(s16, s32, s16, struct TemporaryPool *); /* extern */
? discard_sequence(s16, s32); /* extern */
extern ? D_803B0380;
extern ? gBankLoadStatus;
extern ? gSeqLoadStatus;
extern void *gNotes;
extern ? gSequencePlayers;
extern ? gSequenceChannels;
void *func_800B93BC(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id) {
? *sp34;
u8 sp33;
struct TemporaryPool *sp28;
struct SoundAllocPool *sp24;
s32 sp20;
? *var_v0_4;
? *var_v0_5;
s16 temp_a0;
s16 temp_a2;
s16 temp_v1_2;
s32 temp_a1;
s32 temp_a1_2;
s32 temp_a1_3;
s32 temp_a1_4;
s32 var_a3;
s32 var_v1_2;
s32 var_v1_3;
s32 var_v1_4;
s32 var_v1_5;
struct SoundAllocPool *temp_v1_3;
struct SoundAllocPool *temp_v1_4;
struct TemporaryPool *var_a3_2;
u32 temp_a0_2;
u32 temp_v1;
u32 var_v0_3;
u8 *temp_v0;
u8 *temp_v0_2;
u8 *temp_v0_3;
u8 *temp_v0_4;
u8 *var_v0_8;
u8 *var_v1;
u8 var_t1;
u8 var_t2;
void *var_v0;
void *var_v0_2;
void *var_v0_6;
void *var_v0_7;
var_a3 = arg3;
loop_1:
if (var_a3 == 0) {
var_a3_2 = &arg0->temporary;
if (arg0 == &gSeqLoadedPool) {
sp34 = &gSeqLoadStatus;
sp33 = 0;
} else if (arg0 == &gBankLoadedPool) {
sp33 = 1;
sp34 = &gBankLoadStatus;
} else if (arg0 == &gUnusedLoadedPool) {
sp33 = 2;
sp34 = &D_803B0380;
}
temp_a2 = var_a3_2->entries[0].id;
if (temp_a2 == -1) {
var_t1 = 0;
} else {
var_t1 = *(temp_a2 + sp34);
}
temp_a0 = var_a3_2->entries[1].id;
if (temp_a0 == -1) {
var_t2 = 0;
} else {
var_t2 = *(temp_a0 + sp34);
}
sp20 = (s32) sp33;
if (sp33 == 1) {
if (var_t1 == 4) {
temp_a1 = gMaxSimultaneousNotes;
var_v1_2 = 0;
if (temp_a1 > 0) {
var_v0 = gNotes;
loop_18:
if ((var_v0->unkB2 != temp_a2) || (((u32) var_v0->unkB0 >> 0x1F) == 0)) {
var_v1_2 += 1;
var_v0 += 0xC0;
if (var_v1_2 < temp_a1) {
goto loop_18;
}
}
}
temp_v0 = &gBankLoadStatus + temp_a2;
if (var_v1_2 == temp_a1) {
var_t1 = 3;
if (*temp_v0 != 5) {
*temp_v0 = 3;
}
}
}
if (var_t2 == 4) {
temp_a1_2 = gMaxSimultaneousNotes;
var_v1_3 = 0;
if (temp_a1_2 > 0) {
var_v0_2 = gNotes;
loop_27:
if ((var_v0_2->unkB2 != var_a3_2->entries[1].id) || (((u32) var_v0_2->unkB0 >> 0x1F) == 0)) {
var_v1_3 += 1;
var_v0_2 += 0xC0;
if (var_v1_3 < temp_a1_2) {
goto loop_27;
}
}
}
if (var_v1_3 == temp_a1_2) {
temp_v0_2 = &gBankLoadStatus + var_a3_2->entries[1].id;
var_t2 = 3;
if (*temp_v0_2 != 5) {
*temp_v0_2 = 3;
}
}
}
}
if (var_t1 == 0) {
var_a3_2->nextSide = 0;
var_v0_3 = 0;
goto block_84;
}
if (var_t2 == 0) {
var_v0_3 = 1;
var_a3_2->nextSide = 1;
goto block_84;
}
if ((var_t1 == 3) && (var_t2 == 3)) {
var_v0_3 = var_a3_2->nextSide;
goto block_84;
}
if (var_t1 == 3) {
var_a3_2->nextSide = 0;
var_v0_3 = 0;
goto block_84;
}
if (var_t2 == 3) {
var_v0_3 = 1;
var_a3_2->nextSide = 1;
goto block_84;
}
if (sp20 == 0) {
if (var_t1 == 2) {
var_v0_4 = &gSequencePlayers;
loop_47:
if ((((u32) var_v0_4->unk0 >> 0x1F) == 0) || (var_v0_4->unk4 != var_a3_2->entries[0].id)) {
var_v0_4 += 0x148;
if (var_v0_4 != &gSequenceChannels) {
goto loop_47;
}
}
if (var_v0_4 == &gSequenceChannels) {
var_a3_2->nextSide = 0;
var_v0_3 = 0;
goto block_84;
}
goto block_52;
}
block_52:
if (var_t2 == 2) {
var_v0_5 = &gSequencePlayers;
loop_54:
if ((((u32) var_v0_5->unk0 >> 0x1F) == 0) || (var_v0_5->unk4 != var_a3_2->entries[1].id)) {
var_v0_5 += 0x148;
if (var_v0_5 != &gSequenceChannels) {
goto loop_54;
}
}
var_v0_3 = 1;
if (var_v0_5 == &gSequenceChannels) {
var_a3_2->nextSide = 1;
goto block_84;
}
goto block_76;
}
goto block_76;
}
if (sp20 == (s32) 1U) {
if (var_t1 == 2) {
temp_a1_3 = gMaxSimultaneousNotes;
var_v1_4 = 0;
if (temp_a1_3 > 0) {
var_v0_6 = gNotes;
loop_63:
if ((var_v0_6->unkB2 != var_a3_2->entries[0].id) || (((u32) var_v0_6->unkB0 >> 0x1F) == 0)) {
var_v1_4 += 1;
var_v0_6 += 0xC0;
if (var_v1_4 < temp_a1_3) {
goto loop_63;
}
}
}
var_v0_3 = 0;
if (var_v1_4 == temp_a1_3) {
var_a3_2->nextSide = 0;
goto block_84;
}
goto block_68;
}
block_68:
if (var_t2 == 2) {
temp_a1_4 = gMaxSimultaneousNotes;
var_v1_5 = 0;
if (temp_a1_4 > 0) {
var_v0_7 = gNotes;
loop_71:
if ((var_v0_7->unkB2 != var_a3_2->entries[1].id) || (((u32) var_v0_7->unkB0 >> 0x1F) == 0)) {
var_v1_5 += 1;
var_v0_7 += 0xC0;
if (var_v1_5 < temp_a1_4) {
goto loop_71;
}
}
}
var_v0_3 = 1;
if (var_v1_5 == temp_a1_4) {
var_a3_2->nextSide = 1;
goto block_84;
}
goto block_76;
}
goto block_76;
}
block_76:
var_v0_3 = var_a3_2->nextSide;
if (var_v0_3 == 0) {
if (var_t1 == 1) {
var_v0_3 = 1;
if (var_t2 != 1) {
var_a3_2->nextSide = 1;
goto block_84;
}
goto block_83;
}
goto block_84;
}
if (var_t2 == 1) {
var_v0_3 = 0;
if (var_t1 != 1) {
var_a3_2->nextSide = 0;
goto block_84;
}
block_83:
return NULL;
}
block_84:
temp_v1_2 = var_a3_2->entries[var_v0_3].id;
if (temp_v1_2 != -1) {
*(sp34 + temp_v1_2) = 0;
if (sp20 == (s32) 1U) {
sp28 = var_a3_2;
discard_bank(var_a3_2->entries[var_a3_2->nextSide].id, sp20, var_a3_2->entries[0].id, var_a3_2);
}
}
temp_a0_2 = var_a3_2->nextSide;
temp_v1_3 = &arg0->temporary.pool;
if (temp_a0_2 != 0) {
temp_v1_4 = &arg0->temporary.pool;
if (temp_a0_2 != 1) {
return NULL;
}
var_a3_2->entries[1].id = (s16) id;
var_v0_8 = (&temp_v1_4->start[temp_v1_4->size] - size) - 0x10;
var_a3_2->entries[1].ptr = var_v0_8;
var_a3_2->entries[1].size = (u32) size;
if ((u32) var_v0_8 < (u32) temp_v1_4->cur) {
*(sp34 + var_a3_2->entries[0].id) = 0;
switch (sp20) { /* switch 1; irregular */
case 0: /* switch 1 */
sp28 = var_a3_2;
sp24 = temp_v1_4;
discard_sequence(var_a3_2->entries[0].id, sp20);
block_106:
var_a3_2 = sp28;
break;
case 1: /* switch 1 */
sp28 = var_a3_2;
sp24 = temp_v1_4;
discard_bank(var_a3_2->entries[0].id, sp20);
goto block_106;
}
var_a3_2->entries[0].id = -1;
temp_v1_4->cur = temp_v1_4->start;
var_v0_8 = var_a3_2->entries[1].ptr;
}
var_v1 = var_v0_8;
goto block_99;
}
var_a3_2->entries[0].id = (s16) id;
var_a3_2->entries[0].ptr = temp_v1_3->start;
var_a3_2->entries[0].size = (u32) size;
temp_v0_3 = &temp_v1_3->start[size];
temp_v1_3->cur = temp_v0_3;
if ((u32) var_a3_2->entries[1].ptr < (u32) temp_v0_3) {
*(sp34 + var_a3_2->entries[1].id) = 0;
switch (sp20) { /* irregular */
case 0:
sp28 = var_a3_2;
sp24 = temp_v1_3;
discard_sequence(var_a3_2->entries[1].id, sp20);
block_96:
var_a3_2 = sp28;
break;
case 1:
sp28 = var_a3_2;
sp24 = temp_v1_3;
discard_bank(var_a3_2->entries[1].id, sp20);
goto block_96;
}
var_a3_2->entries[1].id = -1;
var_a3_2->entries[1].ptr = &temp_v1_3->start[temp_v1_3->size];
}
var_v1 = var_a3_2->entries[0].ptr;
block_99:
var_a3_2->nextSide ^= 1;
return var_v1;
}
arg3 = var_a3;
temp_v0_4 = soundAlloc(&arg0->persistent.pool, arg1 * size);
arg0->persistent.entries[arg0->persistent.numEntries].ptr = temp_v0_4;
if (temp_v0_4 == NULL) {
if ((arg3 != 0) && (arg3 != 1)) {
if (arg3 == 2) {
var_a3 = 0;
goto loop_1;
}
goto block_116;
}
return NULL;
}
block_116:
arg0->persistent.entries[arg0->persistent.numEntries].id = (s16) id;
arg0->persistent.entries[arg0->persistent.numEntries].size = (u32) size;
temp_v1 = arg0->persistent.numEntries;
arg0->persistent.numEntries = temp_v1 + 1;
return arg0->persistent.entries[temp_v1].ptr;
}
#else
GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B93BC.s")
#endif
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;
}
#ifdef NEEDS_RODATA
// inspired by func_eu_802e27e4_unused from SM64
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];
}
}
#else
GLOBAL_ASM("asm/non_matchings/audio/heap/func_800B9BE4.s")
#endif
extern s8 gNumSynthesisReverbs;
// inspired by decrease_reverb_gain from SM64
void func_800B9FB8(void) {
s32 i;
for (i = 0; i < gNumSynthesisReverbs; i++) {
gSynthesisReverbs[i].reverbGain -= gSynthesisReverbs[i].reverbGain / 4;
}
}
#ifdef MIPS_TO_C
//generated by mips_to_c commit bd0364fa19633bd6201f8007e2d0a7ed87825909
void func_800B9FB8(); /* extern */
void func_800BA250(); /* extern */
void sequence_player_disable(? *); /* extern */
extern u32 gSequencePlayers;
extern ? gSequenceChannels;
extern ? gAudioBufferParameters;
s32 func_800BA00C(void) {
? *temp_s0;
s32 *temp_v1;
s32 temp_a0;
s32 temp_a2;
s32 temp_v0;
s32 temp_v0_4;
s32 temp_v0_5;
s32 temp_v0_6;
u8 temp_t6;
void *temp_v0_2;
void *temp_v0_3;
? *phi_s0;
s32 phi_v1;
s32 phi_a0;
s32 phi_a2;
s32 *phi_v1_2;
s32 phi_v0;
temp_t6 = D_803B0500;
switch (temp_t6) {
case 5:
phi_s0 = &gSequencePlayers;
do {
sequence_player_disable(phi_s0);
temp_s0 = phi_s0 + 0x148;
phi_s0 = temp_s0;
} while (temp_s0 != &gSequenceChannels);
D_803B0504 = 4;
D_803B0500 += -1;
break;
case 4:
temp_v0 = D_803B0504;
if (temp_v0 != 0) {
D_803B0504 = temp_v0 - 1;
func_800B9FB8();
} else {
temp_a2 = gMaxSimultaneousNotes;
phi_v1 = 0;
phi_a0 = 0;
phi_a2 = temp_a2;
if (temp_a2 > 0) {
do {
temp_a0 = phi_a0 + 1;
temp_v0_2 = gNotes + phi_v1;
phi_a0 = temp_a0;
if (((temp_v0_2->unkB0 >> 0x1F) != 0) && (temp_v0_2->unk59 != 0)) {
temp_v0_2->unk68 = gAudioBufferParameters.unk18;
temp_v0_3 = gNotes + phi_v1;
temp_v0_3->unk58 = temp_v0_3->unk58 | 0x10;
phi_a2 = gMaxSimultaneousNotes;
}
phi_v1 += 0xC0;
} while (temp_a0 < phi_a2);
}
D_803B0504 = 0x10;
D_803B0500 += -1;
}
break;
case 3:
temp_v0_4 = D_803B0504;
phi_v1_2 = &D_803B7180;
if (temp_v0_4 != 0) {
D_803B0504 = temp_v0_4 - 1;
func_800B9FB8();
} else {
do {
phi_v0 = 0;
loop_18:
*(*phi_v1_2 + phi_v0) = 0;
(*phi_v1_2 + phi_v0)->unk2 = 0;
(*phi_v1_2 + phi_v0)->unk4 = 0;
temp_v0_5 = phi_v0 + 8;
(*phi_v1_2 + phi_v0)->unk6 = 0;
phi_v0 = temp_v0_5;
if (temp_v0_5 != 0xA00) {
goto loop_18;
}
temp_v1 = phi_v1_2 + 4;
phi_v1_2 = temp_v1;
} while (temp_v1 != &D_803B718C);
D_803B0504 = 4;
D_803B0500 += -1;
}
break;
case 2:
temp_v0_6 = D_803B0504;
if (temp_v0_6 != 0) {
D_803B0504 = temp_v0_6 - 1;
} else {
D_803B0500 += -1;
}
break;
case 1:
func_800BA250();
D_803B0500 = 0;
break;
}
if (D_803B0500 < 3) {
return 0;
}
return 1;
}
#else
GLOBAL_ASM("asm/non_matchings/audio/heap/func_800BA00C.s")
#endif
#ifdef MIPS_TO_C
//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c
? func_800B8DE0(); /* extern */
? func_800B914C(? *, s16, s16, u16); /* extern */
? init_note_free_list(); /* extern */
? note_init_all(); /* extern */
extern s32 D_803AFBD0;
extern ? D_803B0348;
extern struct PoolSplit2 D_803B0358;
extern struct PoolSplit D_803B0360;
extern struct PoolSplit D_803B0370;
extern u8 D_803B0501;
extern void *gNotes;
extern s32 D_803B70AC;
extern s16 D_803B70B4;
extern ? D_803B70C8;
extern ? D_803B70D0;
extern f32 D_803B7178;
extern s32 D_803B717C;
extern ? sAudioSynthesisPad;
static ? D_800EA4D8; /* unable to generate initializer; const */
static s16 D_800EA5CC; /* unable to generate initializer; const */
void func_800BA250(void) {
? *var_s0;
f32 temp_f0;
s16 *temp_v0_2;
s16 *temp_v0_3;
s16 temp_a1;
s16 temp_a2;
s16 temp_t0;
s16 temp_t1;
s16 temp_v1;
s32 temp_t2;
s32 temp_t9;
s32 var_s1;
s32 var_s5;
struct SynthesisReverb *var_s0_2;
struct SynthesisReverb *var_s2;
struct SynthesisReverb *var_s2_2;
u16 temp_a3;
u16 temp_t7;
u32 temp_s0;
u32 temp_s1;
u8 temp_v1_2;
void *temp_s6;
void *temp_v0;
temp_s6 = (D_803B0501 * 0x28) + &D_800EA4D8;
gSampleDmaNumListItems = 0;
temp_t9 = temp_s6->unk0;
gAudioBufferParameters.frequency = (u16) temp_t9;
gAudioBufferParameters.aiFrequency = osAiSetFrequency(temp_t9 & 0xFFFF);
temp_a3 = gAudioBufferParameters.frequency;
gAudioBufferParameters.samplesPerFrameTarget = (((s32) temp_a3 / (s32) D_803B717C) + 0xF) & 0xFFF0;
temp_v1 = gAudioBufferParameters.samplesPerFrameTarget;
temp_t0 = temp_v1 + 0x10;
gAudioBufferParameters.minAiBufferLength = temp_v1 - 0x10;
gAudioBufferParameters.maxAiBufferLength = temp_t0;
gAudioBufferParameters.updatesPerFrame = (temp_t0 / 192) + 1;
temp_a2 = gAudioBufferParameters.updatesPerFrame;
gAudioBufferParameters.samplesPerUpdate = (temp_v1 / temp_a2) & 0xFFF8;
temp_t1 = gAudioBufferParameters.samplesPerUpdate;
temp_f0 = (f32) temp_a2;
gAudioBufferParameters.samplesPerUpdateMax = temp_t1 + 8;
gAudioBufferParameters.samplesPerUpdateMin = temp_t1 - 8;
gAudioBufferParameters.resampleRate = 32000.0f / (f32) temp_a3;
gAudioBufferParameters.unkUpdatesPerFrameScaled = 0.001171875f / temp_f0;
gAudioBufferParameters.updatesPerFrameInv = 1.0f / temp_f0;
gMaxSimultaneousNotes = (s32) temp_s6->unk5;
gVolume = (s16) temp_s6->unkC;
D_803B70B4 = (s16) (u32) (((temp_f0 * 2880000.0f) / (f32) D_800EA5CC) / D_803B7178);
gAudioBufferParameters.presetUnk4 = (s16) temp_s6->unk4;
temp_a1 = gAudioBufferParameters.presetUnk4;
gAudioBufferParameters.samplesPerFrameTarget = temp_v1 * temp_a1;
gAudioBufferParameters.maxAiBufferLength *= temp_a1;
gAudioBufferParameters.minAiBufferLength *= temp_a1;
gAudioBufferParameters.updatesPerFrame = temp_a2 * temp_a1;
D_803B70AC = (gMaxSimultaneousNotes * 0x14 * gAudioBufferParameters.updatesPerFrame) + (temp_s6->unk6 << 5) + 0x1E0;
temp_s0 = temp_s6->unk10 + temp_s6->unk14 + temp_s6->unk18;
temp_s1 = temp_s6->unk1C + temp_s6->unk20 + temp_s6->unk24;
temp_t2 = temp_s0 + temp_s1;
D_803B0348.unk0 = (s32) ((D_803AFBD0 - temp_t2) - 0x100);
D_803B0348.unkC = temp_t2;
func_800B914C(&D_803B0348, temp_a1, temp_a2, temp_a3);
D_803B0358.wantPersistent = temp_s0;
D_803B0358.wantTemporary = temp_s1;
seq_and_bank_pool_init(&D_803B0358);
D_803B0360.wantSeq = temp_s6->unk10;
D_803B0360.wantBank = temp_s6->unk14;
D_803B0360.wantUnused = temp_s6->unk18;
persistent_pools_init(&D_803B0360);
D_803B0370.wantSeq = temp_s6->unk1C;
D_803B0370.wantBank = temp_s6->unk20;
D_803B0370.wantUnused = temp_s6->unk24;
temporary_pools_init(&D_803B0370);
func_800B8DE0();
gNotes = soundAlloc(&gNotesAndBuffersPool, gMaxSimultaneousNotes * 0xC0);
note_init_all();
init_note_free_list();
gNoteSubsEu = soundAlloc(&gNotesAndBuffersPool, gAudioBufferParameters.updatesPerFrame * gMaxSimultaneousNotes * 0x10);
var_s0 = &D_803B70C8;
do {
var_s0 += 4;
var_s0->unk-4 = soundAlloc(&gNotesAndBuffersPool, D_803B70AC * 8);
} while (var_s0 != &D_803B70D0);
var_s2 = gSynthesisReverbs;
do {
var_s2 += 0x108;
var_s2->unk-107 = 0;
} while ((u32) var_s2 < (u32) &sAudioSynthesisPad);
gNumSynthesisReverbs = (s8) temp_s6->unk6;
var_s2_2 = gSynthesisReverbs;
var_s5 = 0;
if (gNumSynthesisReverbs > 0) {
do {
temp_v0 = temp_s6->unk8 + (var_s5 * 4);
temp_t7 = temp_v0->unk1 << 6;
var_s2_2->windowSize = temp_t7;
var_s2_2->downsampleRate = temp_v0->unk0;
var_s2_2->useReverb = 8;
var_s2_2->reverbGain = temp_v0->unk2;
var_s2_2->ringBuffer.left = soundAlloc(&gNotesAndBuffersPool, (temp_t7 & 0xFFFF) * 2);
temp_v1_2 = var_s2_2->downsampleRate;
var_s2_2->ringBuffer.right = soundAlloc(&gNotesAndBuffersPool, var_s2_2->windowSize * 2);
var_s2_2->nextRingBufferPos = 0;
var_s2_2->unkC = 0;
var_s2_2->curFrame = 0;
var_s2_2->framesLeftToIgnore = 2;
var_s2_2->bufSizePerChannel = (s32) var_s2_2->windowSize;
if (temp_v1_2 != 1) {
var_s2_2->resampleFlags = 1;
var_s2_2->resampleRate = (u16) (0x8000 / (s32) temp_v1_2);
var_s1 = 0;
var_s2_2->resampleStateLeft = soundAlloc(&gNotesAndBuffersPool, 0x00000020U);
var_s2_2->resampleStateRight = soundAlloc(&gNotesAndBuffersPool, 0x00000020U);
var_s2_2->unk24 = soundAlloc(&gNotesAndBuffersPool, 0x00000020U);
var_s2_2->unk28 = soundAlloc(&gNotesAndBuffersPool, 0x00000020U);
if (gAudioBufferParameters.updatesPerFrame > 0) {
var_s0_2 = var_s2_2;
do {
temp_v0_2 = soundAlloc(&gNotesAndBuffersPool, 0x00000300U);
var_s0_2->items[0][0].toDownsampleLeft = temp_v0_2;
var_s0_2->items[0][0].toDownsampleRight = temp_v0_2 + 0x180;
temp_v0_3 = soundAlloc(&gNotesAndBuffersPool, 0x00000300U);
var_s0_2->items[1][0].toDownsampleLeft = temp_v0_3;
var_s0_2->items[1][0].toDownsampleRight = temp_v0_3 + 0x180;
var_s1 += 1;
var_s0_2 += 0x14;
} while (var_s1 < gAudioBufferParameters.updatesPerFrame);
}
}
var_s5 += 1;
var_s2_2 += 0x108;
} while (var_s5 < gNumSynthesisReverbs);
}
func_800BB030(gMaxSimultaneousNotes);
osWritebackDCacheAll();
}
#else
GLOBAL_ASM("asm/non_matchings/audio/heap/func_800BA250.s")
#endif
void *unk_pool1_lookup(s32 poolIdx, s32 id) {
s32 i;
for (i = 0; i < gUnkPool1.pool.numAllocatedEntries; i++) {
if (gUnkPool1.entries[i].poolIndex == poolIdx && gUnkPool1.entries[i].id == id) {
return gUnkPool1.entries[i].ptr;
}
}
return NULL;
}
#ifdef MIPS_TO_C
//generated by m2c commit 0927f17aac197848d4ebdf0c6bbad74b01f0851c
? audio_dma_copy_immediate(s32, u8 *, u32, s32); /* extern */
? func_800BB584(s32); /* extern */
extern ? gBankLoadStatus;
extern ? gSeqLoadStatus;
extern s32 D_803B706C;
extern s32 D_803B7070;
extern s32 D_803B7074;
extern s32 gCtlEntries;
void func_800BA8B0(s16 arg0, s32 arg1) {
s32 sp3C;
s32 sp38;
u32 sp34;
s32 sp30;
void *sp20;
s32 temp_a2;
s32 var_a3;
s32 var_s1;
u32 temp_a1;
u8 *temp_v0_3;
u8 *temp_v0_4;
u8 *temp_v0_5;
void *temp_v0;
void *temp_v0_2;
var_s1 = arg1;
switch (arg0) { /* irregular */
case 0:
sp3C = D_803B706C;
break;
case 1:
sp3C = D_803B7070;
break;
case 2:
sp3C = D_803B7074;
break;
}
temp_v0 = sp3C + (var_s1 * 8);
if (temp_v0->unk8 == 0) {
var_s1 = temp_v0->unk4;
}
if (unk_pool1_lookup((s32) arg0, var_s1) == NULL) {
temp_v0_2 = sp3C + (var_s1 * 8);
temp_a2 = gUnkPool1.pool.numAllocatedEntries;
temp_a1 = temp_v0_2->unk8;
var_a3 = temp_v0_2->unk4;
if (arg0 == 1) {
var_a3 += 0x10;
}
sp34 = temp_a1;
sp38 = temp_a2;
sp30 = var_a3;
temp_v0_3 = soundAlloc(&gUnkPool1.pool, temp_a1);
gUnkPool1.entries[temp_a2].ptr = temp_v0_3;
if (temp_v0_3 != NULL) {
sp20 = (temp_a2 * 0xC) + &gUnkPool1;
audio_dma_copy_immediate(var_a3, temp_v0_3, sp34, var_a3);
gUnkPool1.entries[temp_a2].poolIndex = arg0;
gUnkPool1.entries[temp_a2].id = (s16) var_s1;
gUnkPool1.entries[temp_a2].size = sp34;
switch (arg0) { /* switch 1; irregular */
case 0: /* switch 1 */
temp_v0_4 = var_s1 + &gSeqLoadStatus;
if (*temp_v0_4 != 5) {
*temp_v0_4 = 5;
return;
}
break;
case 1: /* switch 1 */
(gCtlEntries + (var_s1 * 0xC))->unk4 = (u8 *) (gUnkPool1.entries[temp_a2].ptr + 4);
func_800BB584(var_s1);
temp_v0_5 = var_s1 + &gBankLoadStatus;
if (*temp_v0_5 != 5) {
*temp_v0_5 = 5;
}
break;
}
}
} else {
case 2: /* switch 1 */
}
}
#else
GLOBAL_ASM("asm/non_matchings/audio/heap/func_800BA8B0.s")
#endif