1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#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
|