#ifndef _AUDIO_MEMORY_H
#define _AUDIO_MEMORY_H

#include "internal.h"

#define SOUND_LOAD_STATUS_NOT_LOADED     0
#define SOUND_LOAD_STATUS_IN_PROGRESS    1
#define SOUND_LOAD_STATUS_COMPLETE       2
#define SOUND_LOAD_STATUS_DISCARDABLE    3

#define IS_BANK_LOAD_COMPLETE(bankId) (gBankLoadStatus[bankId] >= SOUND_LOAD_STATUS_COMPLETE)
#define IS_SEQ_LOAD_COMPLETE(seqId) (gSeqLoadStatus[seqId] >= SOUND_LOAD_STATUS_COMPLETE)

struct SoundAllocPool
{
    u8 *start;
    u8 *cur;
    u32 size;
    s32 unused; // set to 0, never read
}; // size = 0x10

struct SeqOrBankEntry {
    u8 *ptr;
    u32 size;
    s32 id; // seqId or bankId
}; // size = 0xC

struct PersistentPool
{
    /*0x00*/ u32 numEntries;
    /*0x04*/ struct SoundAllocPool pool;
    /*0x14*/ struct SeqOrBankEntry entries[32];
}; // size = 0x194

struct TemporaryPool
{
    /*0x00*/ u32 nextSide;
    /*0x04*/ struct SoundAllocPool pool;
    /*0x14*/ struct SeqOrBankEntry entries[2];
}; // size = 0x2C

struct SoundMultiPool
{
    /*0x000*/ struct PersistentPool persistent;
    /*0x194*/ struct TemporaryPool temporary;
    /*     */ u32 pad2[4];
}; // size = 0x1D0

extern u8 gAudioHeap[];
extern s16 D_802212A0;
extern s8 D_802212A2;
extern u8 D_802212A3;
extern struct SoundAllocPool gSoundPool;
extern struct SoundAllocPool D_802212C8;
extern struct SoundMultiPool gSeqLoadedPool;
extern struct SoundMultiPool gBankLoadedPool;
extern u8 gBankLoadStatus[64];
extern u8 gSeqLoadStatus[256];

void *soundAlloc(struct SoundAllocPool *pool, u32 size);
void func_80316108(s32 arg0);
void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id);
void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 arg2);
void func_80316928(struct Struct80332190 *arg0);

#endif /* _AUDIO_MEMORY_H */
