summaryrefslogtreecommitdiff
path: root/include/audio
diff options
context:
space:
mode:
authorengineer124 <47598039+engineer124@users.noreply.github.com>2023-08-13 02:33:58 +1000
committerGitHub <noreply@github.com>2023-08-12 12:33:58 -0400
commit05c2221769ffdbbfd774d856bac77b6d7c2413a0 (patch)
treeb93f580f2bdce87a4a1564ae4684cd3dfa660c12 /include/audio
parenta6a94e543c58a4edd20a9a0b76e9def79dfdafdc (diff)
Audio Load and Heap Headers (#1329)
* more header splits * cleanup * adjust comments
Diffstat (limited to 'include/audio')
-rw-r--r--include/audio/effects.h7
-rw-r--r--include/audio/heap.h111
-rw-r--r--include/audio/load.h145
-rw-r--r--include/audio/soundfont.h101
4 files changed, 364 insertions, 0 deletions
diff --git a/include/audio/effects.h b/include/audio/effects.h
index 67741200f..fe71aeb3b 100644
--- a/include/audio/effects.h
+++ b/include/audio/effects.h
@@ -21,6 +21,13 @@ typedef enum AdsrStatus {
/* 8 */ ADSR_STATUS_SUSTAIN
} AdsrStatus;
+// Special commands for `delay` in `EnvelopePoint`
+// Any value above 0 is treated as a delay
+#define ADSR_DISABLE 0
+#define ADSR_HANG -1
+#define ADSR_GOTO -2
+#define ADSR_RESTART -3
+
typedef struct EnvelopePoint {
/* 0x0 */ s16 delay;
/* 0x2 */ s16 arg;
diff --git a/include/audio/heap.h b/include/audio/heap.h
new file mode 100644
index 000000000..33f3dfcd9
--- /dev/null
+++ b/include/audio/heap.h
@@ -0,0 +1,111 @@
+#ifndef AUDIO_HEAP_H
+#define AUDIO_HEAP_H
+
+#include "PR/ultratypes.h"
+#include "libc/stddef.h"
+#include "unk.h"
+
+typedef struct {
+ /* 0x0 */ size_t heapSize; // total number of bytes allocated to the audio heap. Must be <= the size of `gAudioHeap` (ideally about the same size)
+ /* 0x4 */ size_t initPoolSize; // The entire audio heap is split into two pools.
+ /* 0x8 */ size_t permanentPoolSize;
+} AudioHeapInitSizes; // size = 0xC
+
+/**
+ * Meta-data associated with a pool (contain withing the Audio Heap)
+ */
+typedef struct {
+ /* 0x0 */ u8* startAddr; // start addr of the pool
+ /* 0x4 */ u8* curAddr; // address of the next available memory for allocation
+ /* 0x8 */ size_t size; // size of the pool
+ /* 0xC */ s32 count; // number of entries allocated to the pool
+} AudioAllocPool; // size = 0x10
+
+/**
+ * Audio cache entry data to store a single entry containing either a sequence, soundfont, or entire sample banks
+ */
+typedef struct {
+ /* 0x0 */ u8* addr;
+ /* 0x4 */ size_t size;
+ /* 0x8 */ s16 tableType;
+ /* 0xA */ s16 id;
+} AudioCacheEntry; // size = 0xC
+
+/**
+ * Audio cache entry data to store a single entry containing an individual sample
+ */
+typedef struct {
+ /* 0x00 */ s8 inUse;
+ /* 0x01 */ s8 origMedium;
+ /* 0x02 */ u8 sampleBankId;
+ /* 0x03 */ UNK_TYPE1 pad03[0x5];
+ /* 0x08 */ u8* allocatedAddr;
+ /* 0x0C */ void* sampleAddr;
+ /* 0x10 */ size_t size;
+} SampleCacheEntry; // size = 0x14
+
+/**
+ * Audio cache entry data to store individual samples
+ */
+typedef struct {
+ /* 0x000 */ AudioAllocPool pool;
+ /* 0x010 */ SampleCacheEntry entries[128];
+ /* 0xA10 */ s32 numEntries;
+} AudioSampleCache; // size = 0xA14
+
+typedef struct {
+ /* 0x00 */ u32 numEntries;
+ /* 0x04 */ AudioAllocPool pool;
+ /* 0x14 */ AudioCacheEntry entries[16];
+} AudioPersistentCache; // size = 0xD4
+
+typedef struct {
+ /* 0x00 */ u32 nextSide;
+ /* 0x04 */ AudioAllocPool pool;
+ /* 0x14 */ AudioCacheEntry entries[2];
+} AudioTemporaryCache; // size = 0x3C
+
+typedef struct {
+ /* 0x000 */ AudioPersistentCache persistent;
+ /* 0x0D4 */ AudioTemporaryCache temporary;
+ /* 0x100 */ UNK_TYPE1 pad100[0x10];
+} AudioCache; // size = 0x110
+
+typedef struct {
+ /* 0x0 */ size_t persistentCommonPoolSize;
+ /* 0x4 */ size_t temporaryCommonPoolSize;
+} AudioCachePoolSplit; // size = 0x8
+
+typedef struct {
+ /* 0x0 */ size_t seqCacheSize;
+ /* 0x4 */ size_t fontCacheSize;
+ /* 0x8 */ size_t sampleBankCacheSize;
+} AudioCommonPoolSplit; // size = 0xC
+
+typedef struct {
+ /* 0x0 */ size_t miscPoolSize;
+ /* 0x4 */ size_t unusedSizes[2];
+ /* 0xC */ size_t cachePoolSize;
+} AudioSessionPoolSplit; // size = 0x10
+
+void AudioHeap_DiscardFont(s32 fontId);
+void* AudioHeap_WritebackDCache(void* addr, size_t size);
+void* AudioHeap_AllocAttemptExternal(AudioAllocPool* pool, size_t size);
+void* AudioHeap_AllocDmaMemory(AudioAllocPool* pool, size_t size);
+void* AudioHeap_AllocZeroed(AudioAllocPool* pool, size_t size);
+void* AudioHeap_Alloc(AudioAllocPool* pool, size_t size);
+void AudioHeap_InitPool(AudioAllocPool* pool, void* addr, size_t size);
+void AudioHeap_PopPersistentCache(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 AudioHeap_LoadFilter(s16* filter, s32 lowPassCutoff, s32 highPassCutoff);
+s32 AudioHeap_ResetStep(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 sampleBankId, void* sampleAddr, s8 medium, s32 cache);
+void AudioHeap_ApplySampleBankCache(s32 sampleBankId);
+void AudioHeap_SetReverbData(s32 reverbIndex, u32 dataType, s32 data, s32 isFirstInit);
+
+#endif
diff --git a/include/audio/load.h b/include/audio/load.h
new file mode 100644
index 000000000..b5bc01594
--- /dev/null
+++ b/include/audio/load.h
@@ -0,0 +1,145 @@
+#ifndef AUDIO_LOAD_H
+#define AUDIO_LOAD_H
+
+#include "audio/soundfont.h"
+#include "PR/ultratypes.h"
+#include "libc/stddef.h"
+#include "libc/stdint.h"
+#include "ultra64/message.h"
+#include "unk.h"
+#include "os.h"
+
+struct Sample;
+
+typedef s32 (*DmaHandler)(OSPiHandle* handle, OSIoMesg* mb, s32 direction);
+
+typedef enum {
+ /* 0 */ SEQUENCE_TABLE,
+ /* 1 */ FONT_TABLE,
+ /* 2 */ SAMPLE_TABLE
+} SampleBankTableType;
+
+typedef struct {
+ /* 0x0 */ uintptr_t romAddr;
+ /* 0x4 */ size_t size;
+ /* 0x8 */ s8 medium;
+ /* 0x9 */ s8 cachePolicy;
+ /* 0xA */ s16 shortData1;
+ /* 0xC */ s16 shortData2;
+ /* 0xE */ s16 shortData3;
+} AudioTableEntry; // size = 0x10
+
+typedef struct {
+ /* 0x00 */ s16 numEntries;
+ /* 0x02 */ s16 unkMediumParam;
+ /* 0x04 */ uintptr_t romAddr;
+ /* 0x08 */ char pad[0x8];
+ /* 0x10 */ AudioTableEntry entries[1]; // (dynamic size)
+} AudioTable; // size >= 0x20
+
+typedef enum {
+ /* 0 */ LOAD_STATUS_NOT_LOADED,
+ /* 1 */ LOAD_STATUS_IN_PROGRESS,
+ /* 2 */ LOAD_STATUS_COMPLETE,
+ /* 3 */ LOAD_STATUS_DISCARDABLE,
+ /* 4 */ LOAD_STATUS_MAYBE_DISCARDABLE,
+ /* 5 */ LOAD_STATUS_PERMANENT
+} AudioLoadStatus;
+
+typedef enum {
+ /* 0 */ CACHE_TEMPORARY,
+ /* 1 */ CACHE_PERSISTENT,
+ /* 2 */ CACHE_EITHER,
+ /* 3 */ CACHE_PERMANENT
+} AudioCacheType;
+
+typedef enum {
+ /* 0 */ CACHE_LOAD_PERMANENT,
+ /* 1 */ CACHE_LOAD_PERSISTENT,
+ /* 2 */ CACHE_LOAD_TEMPORARY,
+ /* 3 */ CACHE_LOAD_EITHER,
+ /* 4 */ CACHE_LOAD_EITHER_NOSYNC
+} AudioCacheLoadType;
+
+typedef struct {
+ /* 0x00 */ s8 status;
+ /* 0x01 */ s8 delay;
+ /* 0x02 */ s8 medium;
+ /* 0x04 */ u8* ramAddr;
+ /* 0x08 */ uintptr_t curDevAddr;
+ /* 0x0C */ u8* curRamAddr;
+ /* 0x10 */ size_t bytesRemaining;
+ /* 0x14 */ size_t chunkSize;
+ /* 0x18 */ s32 unkMediumParam;
+ /* 0x1C */ u32 retMsg;
+ /* 0x20 */ OSMesgQueue* retQueue;
+ /* 0x24 */ OSMesgQueue msgQueue;
+ /* 0x3C */ OSMesg msg;
+ /* 0x40 */ OSIoMesg ioMesg;
+} AudioAsyncLoad; // size = 0x58
+
+typedef struct {
+ /* 0x00 */ u8 medium;
+ /* 0x01 */ u8 seqOrFontId;
+ /* 0x02 */ u16 instId;
+ /* 0x04 */ s32 unkMediumParam;
+ /* 0x08 */ uintptr_t curDevAddr;
+ /* 0x0C */ u8* curRamAddr;
+ /* 0x10 */ u8* ramAddr;
+ /* 0x14 */ s32 status;
+ /* 0x18 */ size_t bytesRemaining;
+ /* 0x1C */ s8* isDone; // TODO: rename in OoT and sync up here. This is an external status while (s32 status) is an internal status
+ /* 0x20 */ struct Sample sample;
+ /* 0x30 */ OSMesgQueue msgqueue;
+ /* 0x48 */ OSMesg msg;
+ /* 0x4C */ OSIoMesg ioMesg;
+} AudioSlowLoad; // size = 0x64
+
+typedef struct {
+ /* 0x0 */ u8* ramAddr;
+ /* 0x4 */ uintptr_t devAddr;
+ /* 0x8 */ u16 sizeUnused;
+ /* 0xA */ u16 size;
+ /* 0xC */ u8 unused;
+ /* 0xD */ u8 reuseIndex; // position in sSampleDmaReuseQueue1/2, if ttl == 0
+ /* 0xE */ u8 ttl; // Time To Live: duration after which the DMA can be discarded
+} SampleDma; // size = 0x10
+
+typedef struct {
+ /* 0x00 */ u32 endAndMediumKey;
+ /* 0x04 */ struct Sample* sample;
+ /* 0x08 */ u8* ramAddr;
+ /* 0x0C */ u32 encodedInfo;
+ /* 0x10 */ s32 isFree;
+} AudioPreloadReq; // size = 0x14
+
+void AudioLoad_DecreaseSampleDmaTtls(void);
+void* AudioLoad_DmaSampleData(uintptr_t devAddr, size_t size, s32 arg2, u8* dmaIndexRef, s32 medium);
+void AudioLoad_InitSampleDmaBuffers(s32 numNotes);
+s32 AudioLoad_IsFontLoadComplete(s32 fontId);
+s32 AudioLoad_IsSeqLoadComplete(s32 seqId);
+void AudioLoad_SetFontLoadStatus(s32 fontId, s32 loadStatus);
+void AudioLoad_SetSeqLoadStatus(s32 seqId, s32 loadStatus);
+void AudioLoad_SyncLoadSeqParts(s32 seqId, s32 arg1, s32 arg2, OSMesgQueue* arg3);
+s32 AudioLoad_SyncLoadInstrument(s32 fontId, s32 instId, s32 drumId);
+void AudioLoad_AsyncLoadSeq(s32 seqId, s32 arg1, s32 retData, OSMesgQueue* retQueue);
+void AudioLoad_AsyncLoadSampleBank(s32 sampleBankId, s32 arg1, s32 retData, OSMesgQueue* retQueue);
+void AudioLoad_AsyncLoadFont(s32 fontId, s32 arg1, s32 retData, OSMesgQueue* retQueue);
+u8* AudioLoad_GetFontsForSequence(s32 seqId, u32* outNumFonts);
+void AudioLoad_DiscardSeqFonts(s32 seqId);
+void func_8018FA60(u32 tableType, u32 id, s32 type, s32 data);
+s32 AudioLoad_SyncInitSeqPlayer(s32 playerIndex, s32 seqId, s32 arg2);
+s32 AudioLoad_SyncInitSeqPlayerSkipTicks(s32 playerIndex, s32 seqId, s32 skipTicks);
+void AudioLoad_ProcessLoads(s32 resetStatus);
+void AudioLoad_SetDmaHandler(DmaHandler callback);
+void AudioLoad_Init(void* heap, u32 heapSize);
+void AudioLoad_InitSlowLoads(void);
+s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone);
+s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* isDone);
+void AudioLoad_InitAsyncLoads(void);
+void AudioLoad_LoadPermanentSamples(void);
+void AudioLoad_ScriptLoad(s32 tableType, s32 id, s8* isDone);
+void AudioLoad_ProcessScriptLoads(void);
+void AudioLoad_InitScriptLoads(void);
+
+#endif
diff --git a/include/audio/soundfont.h b/include/audio/soundfont.h
new file mode 100644
index 000000000..0141d9f8c
--- /dev/null
+++ b/include/audio/soundfont.h
@@ -0,0 +1,101 @@
+#ifndef AUDIO_SOUNDFONT_H
+#define AUDIO_SOUNDFONT_H
+
+#include "PR/ultratypes.h"
+
+struct EnvelopePoint;
+
+typedef struct AdpcmLoop {
+ /* 0x00 */ u32 start;
+ /* 0x04 */ u32 loopEnd; // numSamples position into the sample where the loop ends
+ /* 0x08 */ u32 count; // The number of times the loop is played before the sound completes. Setting count to -1 indicates that the loop should play indefinitely.
+ /* 0x0C */ u32 sampleEnd; // total number of s16-samples in the sample audio clip
+ /* 0x10 */ s16 predictorState[16]; // only exists if count != 0. 8-byte aligned
+} AdpcmLoop; // size = 0x30 (or 0x10)
+
+/**
+ * The procedure used to design the codeBook is based on an adaptive clustering algorithm.
+ * The size of the codeBook is (8 * order * numPredictors) and is 8-byte aligned
+ */
+typedef struct AdpcmBook {
+ /* 0x0 */ s32 order;
+ /* 0x4 */ s32 numPredictors;
+ /* 0x8 */ s16 codeBook[1]; // a table of prediction coefficients that the coder selects from to optimize sound quality.
+} AdpcmBook; // size >= 0x8
+
+typedef enum SampleCodec {
+ /* 0 */ CODEC_ADPCM, // 16 2-byte samples (32 bytes) compressed into 4-bit samples (8 bytes) + 1 header byte
+ /* 1 */ CODEC_S8, // 16 2-byte samples (32 bytes) compressed into 8-bit samples (16 bytes)
+ /* 2 */ CODEC_S16_INMEMORY,
+ /* 3 */ CODEC_SMALL_ADPCM, // 16 2-byte samples (32 bytes) compressed into 2-bit samples (4 bytes) + 1 header byte
+ /* 4 */ CODEC_REVERB,
+ /* 5 */ CODEC_S16,
+ /* 6 */ CODEC_UNK6,
+ /* 7 */ CODEC_UNK7 // processed as uncompressed samples
+} SampleCodec;
+
+typedef enum SampleMedium {
+ /* 0 */ MEDIUM_RAM,
+ /* 1 */ MEDIUM_UNK,
+ /* 2 */ MEDIUM_CART,
+ /* 3 */ MEDIUM_DISK_DRIVE,
+ /* 5 */ MEDIUM_RAM_UNLOADED = 5
+} SampleMedium;
+
+typedef struct Sample {
+ /* 0x0 */ u32 unk_0 : 1;
+ /* 0x0 */ u32 codec : 3; // The state of compression or decompression, See `SampleCodec`
+ /* 0x0 */ u32 medium : 2; // Medium where sample is currently stored. See `SampleMedium`
+ /* 0x0 */ u32 unk_bit26 : 1;
+ /* 0x0 */ u32 isRelocated : 1; // Has the sample header been relocated (offsets to pointers)
+ /* 0x1 */ u32 size : 24; // Size of the sample
+ /* 0x4 */ u8* sampleAddr; // Raw sample data. Offset from the start of the sample bank or absolute address to either rom or ram
+ /* 0x8 */ AdpcmLoop* loop; // Adpcm loop parameters used by the sample. Offset from the start of the sound font / pointer to ram
+ /* 0xC */ AdpcmBook* book; // Adpcm book parameters used by the sample. Offset from the start of the sound font / pointer to ram
+} Sample; // size = 0x10
+
+typedef struct TunedSample {
+ /* 0x0 */ Sample* sample;
+ /* 0x4 */ f32 tuning; // frequency scale factor
+} TunedSample; // size = 0x8
+
+/**
+ * Stores an entry of decompressed samples in a reverb ring buffer.
+ * By storing the sample in a ring buffer, the time it takes to loop
+ * around back to the same sample acts as a delay, leading to an echo effect.
+ */
+typedef struct Instrument {
+ /* 0x00 */ u8 isRelocated; // have the envelope and all samples been relocated (offsets to pointers)
+ /* 0x01 */ u8 normalRangeLo;
+ /* 0x02 */ u8 normalRangeHi;
+ /* 0x03 */ u8 adsrDecayIndex; // index used to obtain adsr decay rate from adsrDecayTable
+ /* 0x04 */ struct EnvelopePoint* envelope;
+ /* 0x08 */ TunedSample lowPitchTunedSample;
+ /* 0x10 */ TunedSample normalPitchTunedSample;
+ /* 0x18 */ TunedSample highPitchTunedSample;
+} Instrument; // size = 0x20
+
+typedef struct Drum {
+ /* 0x0 */ u8 adsrDecayIndex; // index used to obtain adsr decay rate from adsrDecayTable
+ /* 0x1 */ u8 pan;
+ /* 0x2 */ u8 isRelocated; // have tunedSample.sample and envelope been relocated (offsets to pointers)
+ /* 0x4 */ TunedSample tunedSample;
+ /* 0xC */ struct EnvelopePoint* envelope;
+} Drum; // size = 0x10
+
+typedef struct SoundEffect {
+ /* 0x0 */ TunedSample tunedSample;
+} SoundEffect; // size = 0x8
+
+typedef struct SoundFont {
+ /* 0x00 */ u8 numInstruments;
+ /* 0x01 */ u8 numDrums;
+ /* 0x02 */ u8 sampleBankId1;
+ /* 0x03 */ u8 sampleBankId2;
+ /* 0x04 */ u16 numSfx;
+ /* 0x08 */ Instrument** instruments;
+ /* 0x0C */ Drum** drums;
+ /* 0x10 */ SoundEffect* soundEffects;
+} SoundFont; // size = 0x14
+
+#endif