Files
SpaghettiKart/src/audio/synthesis.h
T
2024-11-29 14:24:33 -06:00

132 lines
5.1 KiB
C

#ifndef AUDIO_SYNTHESIS_H
#define AUDIO_SYNTHESIS_H
#include "audio/internal.h"
#include <libultra/gbi.h>
#define DEFAULT_LEN_1CH 0x180
#define DEFAULT_LEN_2CH 0x300
#define DMEM_ADDR_TEMP 0x0
#define DMEM_ADDR_RESAMPLED 0x20
#define DMEM_ADDR_RESAMPLED2 0x1A0
#define DMEM_ADDR_UNCOMPRESSED_NOTE 0x180
#define DMEM_ADDR_NOTE_PAN_TEMP 0x200
#define DMEM_ADDR_STEREO_STRONG_TEMP_DRY 0x200
#define DMEM_ADDR_STEREO_STRONG_TEMP_WET 0x340
#define DMEM_ADDR_COMPRESSED_ADPCM_DATA 0x3f0
#define DMEM_ADDR_LEFT_CH 0x540
#define DMEM_ADDR_RIGHT_CH 0x6C0
#define DMEM_ADDR_WET_LEFT_CH 0x840
#define DMEM_ADDR_WET_RIGHT_CH 0x9C0
/*
Its not clear what values these macros should have. Neither version seem to
line up for MK64. Maybe each game has unique values for these? I don't know
enough about the Audio engine stuff to speculate beyond that.
Non-Shindou SM64
#define DMEM_ADDR_TEMP 0x0
#define DMEM_ADDR_RESAMPLED 0x20
#define DMEM_ADDR_RESAMPLED2 0x160
#define DMEM_ADDR_UNCOMPRESSED_NOTE 0x180
#define DMEM_ADDR_NOTE_PAN_TEMP 0x200
#define DMEM_ADDR_STEREO_STRONG_TEMP_DRY 0x200
#define DMEM_ADDR_STEREO_STRONG_TEMP_WET 0x340
#define DMEM_ADDR_COMPRESSED_ADPCM_DATA 0x3f0
#define DMEM_ADDR_LEFT_CH 0x4c0
#define DMEM_ADDR_RIGHT_CH 0x600
#define DMEM_ADDR_WET_LEFT_CH 0x740
#define DMEM_ADDR_WET_RIGHT_CH 0x880
Shindou SM64
#define DMEM_ADDR_TEMP 0x450
#define DMEM_ADDR_RESAMPLED 0x470
#define DMEM_ADDR_RESAMPLED2 0x5f0
#define DMEM_ADDR_UNCOMPRESSED_NOTE 0x5f0
#define DMEM_ADDR_NOTE_PAN_TEMP 0x650
#define DMEM_ADDR_COMPRESSED_ADPCM_DATA 0x990
#define DMEM_ADDR_LEFT_CH 0x990
#define DMEM_ADDR_RIGHT_CH 0xb10
#define DMEM_ADDR_WET_LEFT_CH 0xc90
#define DMEM_ADDR_WET_RIGHT_CH 0xe10
*/
#define MAX_UPDATES_PER_FRAME 5
struct ReverbRingBufferItem {
/* 0x00 */ s16 numSamplesAfterDownsampling;
/* 0x02 */ s16 chunkLen; // never read
/* 0x04 */ s16* toDownsampleLeft;
/* 0x08 */ s16* toDownsampleRight; // data pointed to by left and right are adjacent in memory
/* 0x0C */ s32 startPos; // start pos in ring buffer
/* 0x10 */ s16 lengthA; // first length in ring buffer (from startPos, at most until end)
/* 0x12 */ s16 lengthB; // second length in ring buffer (from pos 0)
}; // size = 0x14
struct SynthesisReverb {
/* 0x00 */ u8 resampleFlags;
/* 0x01 */ u8 useReverb;
/* 0x02 */ u8 framesLeftToIgnore;
/* 0x03 */ u8 curFrame;
/* 0x04 */ u8 downsampleRate;
/* 0x05 */ // u8 compilerPadding;
/* 0x06 */ u16 windowSize; // same as bufSizePerChannel
/* 0x08 */ u16 reverbGain;
/* 0x0A */ u16 resampleRate;
/* 0x0C */ s32 nextRingBufferPos;
/* 0x10 */ s32 unkC; // never read
/* 0x14 */ s32 bufSizePerChannel;
struct {
/* 0x18 */ s16* left;
/* 0x1C */ s16* right;
} ringBuffer;
/* 0x20 */ s16* resampleStateLeft;
/* 0x24 */ s16* resampleStateRight;
/* 0x28 */ s16* unk24; // never read
/* 0x2C */ s16* unk28; // never read
/* 0x30 */ struct ReverbRingBufferItem items[2][MAX_UPDATES_PER_FRAME];
/* 0xF8 */ s16* unkF8;
/* 0xFC */ s16* unkFC;
/* 0x100 */ s16* unk100;
/* 0x104 */ s16* unk104;
}; // size = 0x108
#define ALIGN(val, amnt) (((val) + (1 << amnt) - 1) & ~((1 << amnt) - 1))
void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex, s32 reverbIndex);
Acmd* synthesis_load_reverb_ring_buffer(Acmd*, u16, u16, s32, s32);
Acmd* synthesis_save_reverb_ring_buffer(Acmd*, u16, u16, s32, s32);
void func_800B6FB4(s32 updateIndexStart, s32 noteIndex);
void synthesis_load_note_subs_eu(s32 updateIndex);
Acmd* synthesis_execute(Acmd*, s32*, s16*, s32);
Acmd* synthesis_resample_and_mix_reverb(Acmd*, s32, s16, s16);
Acmd* synthesis_save_reverb_samples(Acmd*, s16, s16);
Acmd* synthesis_do_one_audio_update(s16*, s32, Acmd*, s32);
Acmd* synthesis_process_note(s32 noteIndex, struct NoteSubEu* noteSubEu, struct NoteSynthesisState* synthesisState,
s16* aiBuf, s32 inBuf, Acmd* cmd, s32 updateIndex);
Acmd* load_wave_samples(Acmd* acmd, struct NoteSubEu* noteSubEu, struct NoteSynthesisState* synthesisState,
s32 nSamplesToLoad);
Acmd* final_resample(Acmd* acmd, struct NoteSynthesisState* synthesisState, s32 count, u16 pitch, u16 dmemIn,
u32 flags);
Acmd* func_800B86A0(Acmd* cmd, struct NoteSubEu* note, struct NoteSynthesisState* synthesisState, s32 nSamples,
u16 inBuf, s32 headsetPanSettings, u32 flags);
Acmd* note_apply_headset_pan_effects(Acmd* acmd, struct NoteSubEu* noteSubEu, struct NoteSynthesisState* note,
s32 bufLen, s32 flags, s32 leftRight);
extern struct SynthesisReverb gSynthesisReverbs[4];
/*
SO
gLeftVolRampings is almost certainly gAudioSessionPool (D_803AFBC8) in disguise, but since
synthesis' ro/data has already been broken out it'll be very hard to fix that.
extern f32 gLeftVolRampings[3][1024];
extern f32 gRightVolRampings[3][1024];
extern f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above
extern f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above
*/
#endif // AUDIO_SYNTHESIS_H