mirror of
https://github.com/zeldaret/oot.git
synced 2025-07-17 21:35:11 +00:00
Audio Misc Docs and Cleanup (#1221)
* Audio Cleanup * more * missed one * Audio docs imported from MM * Suggestions from Discord * Small fix * Fix sizes in z64audio.h * numSamples * Cleanup comments * Revert overlap with soundFont PR * revert Audio_AdsrUpdate cleanup (move to different PR) * PR Suggestion * Mainly typos * PR suggestion, vol -> volume * Better description * Name sampling frequency * A good number of PR suggestions * Missed a suggestion * More PR Suggestions Co-authored-by: fig02 <fig02srl@gmail.com>
This commit is contained in:
parent
1738b19d63
commit
e989cb7ace
12 changed files with 1177 additions and 907 deletions
|
@ -4,6 +4,7 @@
|
|||
#define DEFAULT_LEN_1CH 0x1A0
|
||||
#define DEFAULT_LEN_2CH 0x340
|
||||
|
||||
// DMEM Addresses for the RSP
|
||||
#define DMEM_TEMP 0x3C0
|
||||
#define DMEM_UNCOMPRESSED_NOTE 0x580
|
||||
#define DMEM_NOTE_PAN_TEMP 0x5C0
|
||||
|
@ -30,10 +31,10 @@ Acmd* AudioSynth_ProcessEnvelope(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
Acmd* AudioSynth_FinalResample(Acmd* cmd, NoteSynthesisState* synthState, s32 count, u16 pitch, u16 inpDmem,
|
||||
s32 resampleFlags);
|
||||
|
||||
u32 D_801304A0 = 0x13000000;
|
||||
u32 D_801304A4 = 0x5CAEC8E2;
|
||||
u32 D_801304A8 = 0x945CC8E2;
|
||||
u32 D_801304AC = 0x94AEC8E2;
|
||||
u32 D_801304A0 = _SHIFTL(A_ENVMIXER, 24, 8);
|
||||
u32 D_801304A4 = MK_CMD(DMEM_NOTE_PAN_TEMP >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4);
|
||||
u32 D_801304A8 = MK_CMD(DMEM_LEFT_CH >> 4, DMEM_NOTE_PAN_TEMP >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4);
|
||||
u32 D_801304AC = MK_CMD(DMEM_LEFT_CH >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4);
|
||||
|
||||
u16 D_801304B0[] = {
|
||||
0x7FFF, 0xD001, 0x3FFF, 0xF001, 0x5FFF, 0x9001, 0x7FFF, 0x8001,
|
||||
|
@ -41,20 +42,20 @@ u16 D_801304B0[] = {
|
|||
|
||||
u8 D_801304C0[] = { 0x40, 0x20, 0x10, 0x8 };
|
||||
|
||||
void AudioSynth_InitNextRingBuf(s32 chunkLen, s32 bufIndex, s32 reverbIndex) {
|
||||
void AudioSynth_InitNextRingBuf(s32 chunkLen, s32 updateIndex, s32 reverbIndex) {
|
||||
ReverbRingBufferItem* bufItem;
|
||||
s32 pad[3];
|
||||
SynthesisReverb* reverb = &gAudioContext.synthesisReverbs[reverbIndex];
|
||||
s32 temp_a0_2;
|
||||
s32 temp_a0_4;
|
||||
s32 sampleCnt;
|
||||
s32 numSamples;
|
||||
s32 extraSamples;
|
||||
s32 i;
|
||||
s32 j;
|
||||
|
||||
if (reverb->downsampleRate >= 2) {
|
||||
if (reverb->framesToIgnore == 0) {
|
||||
bufItem = &reverb->items[reverb->curFrame][bufIndex];
|
||||
bufItem = &reverb->items[reverb->curFrame][updateIndex];
|
||||
Audio_InvalDCache(bufItem->toDownsampleLeft, DEFAULT_LEN_2CH);
|
||||
|
||||
for (j = 0, i = 0; i < bufItem->lengthA / 2; j += reverb->downsampleRate, i++) {
|
||||
|
@ -69,23 +70,24 @@ void AudioSynth_InitNextRingBuf(s32 chunkLen, s32 bufIndex, s32 reverbIndex) {
|
|||
}
|
||||
}
|
||||
|
||||
bufItem = &reverb->items[reverb->curFrame][bufIndex];
|
||||
sampleCnt = chunkLen / reverb->downsampleRate;
|
||||
extraSamples = (sampleCnt + reverb->nextRingBufPos) - reverb->bufSizePerChan;
|
||||
bufItem = &reverb->items[reverb->curFrame][updateIndex];
|
||||
numSamples = chunkLen / reverb->downsampleRate;
|
||||
extraSamples = (numSamples + reverb->nextRingBufPos) - reverb->bufSizePerChan;
|
||||
temp_a0_2 = reverb->nextRingBufPos;
|
||||
if (extraSamples < 0) {
|
||||
bufItem->lengthA = sampleCnt * 2;
|
||||
bufItem->lengthA = numSamples * 2;
|
||||
bufItem->lengthB = 0;
|
||||
bufItem->startPos = reverb->nextRingBufPos;
|
||||
reverb->nextRingBufPos += sampleCnt;
|
||||
reverb->nextRingBufPos += numSamples;
|
||||
} else {
|
||||
bufItem->lengthA = (sampleCnt - extraSamples) * 2;
|
||||
// End of the buffer is reached. Loop back around
|
||||
bufItem->lengthA = (numSamples - extraSamples) * 2;
|
||||
bufItem->lengthB = extraSamples * 2;
|
||||
bufItem->startPos = reverb->nextRingBufPos;
|
||||
reverb->nextRingBufPos = extraSamples;
|
||||
}
|
||||
|
||||
bufItem->numSamplesAfterDownsampling = sampleCnt;
|
||||
bufItem->numSamplesAfterDownsampling = numSamples;
|
||||
bufItem->chunkLen = chunkLen;
|
||||
|
||||
if (reverb->unk_14 != 0) {
|
||||
|
@ -93,30 +95,31 @@ void AudioSynth_InitNextRingBuf(s32 chunkLen, s32 bufIndex, s32 reverbIndex) {
|
|||
if (temp_a0_4 >= reverb->bufSizePerChan) {
|
||||
temp_a0_4 -= reverb->bufSizePerChan;
|
||||
}
|
||||
bufItem = &reverb->items2[reverb->curFrame][bufIndex];
|
||||
sampleCnt = chunkLen / reverb->downsampleRate;
|
||||
extraSamples = (temp_a0_4 + sampleCnt) - reverb->bufSizePerChan;
|
||||
bufItem = &reverb->items2[reverb->curFrame][updateIndex];
|
||||
numSamples = chunkLen / reverb->downsampleRate;
|
||||
extraSamples = (temp_a0_4 + numSamples) - reverb->bufSizePerChan;
|
||||
if (extraSamples < 0) {
|
||||
bufItem->lengthA = sampleCnt * 2;
|
||||
bufItem->lengthA = numSamples * 2;
|
||||
bufItem->lengthB = 0;
|
||||
bufItem->startPos = temp_a0_4;
|
||||
} else {
|
||||
bufItem->lengthA = (sampleCnt - extraSamples) * 2;
|
||||
// End of the buffer is reached. Loop back around
|
||||
bufItem->lengthA = (numSamples - extraSamples) * 2;
|
||||
bufItem->lengthB = extraSamples * 2;
|
||||
bufItem->startPos = temp_a0_4;
|
||||
}
|
||||
bufItem->numSamplesAfterDownsampling = sampleCnt;
|
||||
bufItem->numSamplesAfterDownsampling = numSamples;
|
||||
bufItem->chunkLen = chunkLen;
|
||||
}
|
||||
}
|
||||
|
||||
void func_800DB03C(s32 arg0) {
|
||||
void func_800DB03C(s32 updateIndex) {
|
||||
NoteSubEu* subEu;
|
||||
NoteSubEu* subEu2;
|
||||
s32 baseIndex;
|
||||
s32 i;
|
||||
|
||||
baseIndex = gAudioContext.numNotes * arg0;
|
||||
baseIndex = gAudioContext.numNotes * updateIndex;
|
||||
for (i = 0; i < gAudioContext.numNotes; i++) {
|
||||
subEu = &gAudioContext.notes[i].noteSubEu;
|
||||
subEu2 = &gAudioContext.noteSubsEu[baseIndex + i];
|
||||
|
@ -146,6 +149,7 @@ Acmd* AudioSynth_Update(Acmd* cmdStart, s32* cmdCnt, s16* aiStart, s32 aiBufLen)
|
|||
|
||||
aiBufP = aiStart;
|
||||
gAudioContext.curLoadedBook = NULL;
|
||||
|
||||
for (i = gAudioContext.audioBufferParameters.updatesPerFrame; i > 0; i--) {
|
||||
if (i == 1) {
|
||||
chunkLen = aiBufLen;
|
||||
|
@ -180,22 +184,22 @@ Acmd* AudioSynth_Update(Acmd* cmdStart, s32* cmdCnt, s16* aiStart, s32 aiBufLen)
|
|||
return cmdP;
|
||||
}
|
||||
|
||||
void func_800DB2C0(s32 updateIndexStart, s32 noteIndex) {
|
||||
NoteSubEu* temp_v1;
|
||||
void func_800DB2C0(s32 updateIndex, s32 noteIndex) {
|
||||
NoteSubEu* noteSubEu;
|
||||
s32 i;
|
||||
|
||||
for (i = updateIndexStart + 1; i < gAudioContext.audioBufferParameters.updatesPerFrame; i++) {
|
||||
temp_v1 = &gAudioContext.noteSubsEu[(gAudioContext.numNotes * i) + noteIndex];
|
||||
if (!temp_v1->bitField0.needsInit) {
|
||||
temp_v1->bitField0.enabled = 0;
|
||||
for (i = updateIndex + 1; i < gAudioContext.audioBufferParameters.updatesPerFrame; i++) {
|
||||
noteSubEu = &gAudioContext.noteSubsEu[(gAudioContext.numNotes * i) + noteIndex];
|
||||
if (!noteSubEu->bitField0.needsInit) {
|
||||
noteSubEu->bitField0.enabled = false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Acmd* AudioSynth_LoadRingBuffer1AtTemp(Acmd* cmd, SynthesisReverb* reverb, s16 bufIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][bufIndex];
|
||||
Acmd* AudioSynth_LoadRingBuffer1AtTemp(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][updateIndex];
|
||||
|
||||
cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_TEMP, bufItem->startPos, bufItem->lengthA, reverb);
|
||||
if (bufItem->lengthB != 0) {
|
||||
|
@ -205,8 +209,8 @@ Acmd* AudioSynth_LoadRingBuffer1AtTemp(Acmd* cmd, SynthesisReverb* reverb, s16 b
|
|||
return cmd;
|
||||
}
|
||||
|
||||
Acmd* AudioSynth_SaveRingBuffer1AtTemp(Acmd* cmd, SynthesisReverb* reverb, s16 bufIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][bufIndex];
|
||||
Acmd* AudioSynth_SaveRingBuffer1AtTemp(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][updateIndex];
|
||||
|
||||
cmd = AudioSynth_SaveRingBufferPart(cmd, DMEM_WET_TEMP, bufItem->startPos, bufItem->lengthA, reverb);
|
||||
if (bufItem->lengthB != 0) {
|
||||
|
@ -216,16 +220,18 @@ Acmd* AudioSynth_SaveRingBuffer1AtTemp(Acmd* cmd, SynthesisReverb* reverb, s16 b
|
|||
return cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leak some audio from the left reverb channel into the right reverb channel and vice versa (pan)
|
||||
*/
|
||||
Acmd* AudioSynth_LeakReverb(Acmd* cmd, SynthesisReverb* reverb) {
|
||||
// Leak some audio from the left reverb channel into the right reverb channel and vice versa (pan)
|
||||
aDMEMMove(cmd++, DMEM_WET_LEFT_CH, DMEM_WET_SCRATCH, DEFAULT_LEN_1CH);
|
||||
aMix(cmd++, 0x1A, reverb->leakRtl, DMEM_WET_RIGHT_CH, DMEM_WET_LEFT_CH);
|
||||
aMix(cmd++, 0x1A, reverb->leakLtr, DMEM_WET_SCRATCH, DMEM_WET_RIGHT_CH);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
Acmd* func_800DB4E4(Acmd* cmd, s32 arg1, SynthesisReverb* reverb, s16 arg3) {
|
||||
ReverbRingBufferItem* item = &reverb->items[reverb->curFrame][arg3];
|
||||
Acmd* func_800DB4E4(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
ReverbRingBufferItem* item = &reverb->items[reverb->curFrame][updateIndex];
|
||||
s16 offsetA;
|
||||
s16 offsetB;
|
||||
|
||||
|
@ -236,15 +242,15 @@ Acmd* func_800DB4E4(Acmd* cmd, s32 arg1, SynthesisReverb* reverb, s16 arg3) {
|
|||
// Ring buffer wrapped
|
||||
cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_TEMP + offsetB, 0, DEFAULT_LEN_1CH - offsetB, reverb);
|
||||
}
|
||||
aSetBuffer(cmd++, 0, DMEM_WET_TEMP + offsetA, DMEM_WET_LEFT_CH, arg1 * 2);
|
||||
aSetBuffer(cmd++, 0, DMEM_WET_TEMP + offsetA, DMEM_WET_LEFT_CH, aiBufLen * 2);
|
||||
aResample(cmd++, reverb->resampleFlags, reverb->unk_0E, reverb->unk_30);
|
||||
aSetBuffer(cmd++, 0, DMEM_WET_TEMP + DEFAULT_LEN_1CH + offsetA, DMEM_WET_RIGHT_CH, arg1 * 2);
|
||||
aSetBuffer(cmd++, 0, DMEM_WET_TEMP + DEFAULT_LEN_1CH + offsetA, DMEM_WET_RIGHT_CH, aiBufLen * 2);
|
||||
aResample(cmd++, reverb->resampleFlags, reverb->unk_0E, reverb->unk_34);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
Acmd* func_800DB680(Acmd* cmd, SynthesisReverb* reverb, s16 bufIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][bufIndex];
|
||||
Acmd* func_800DB680(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][updateIndex];
|
||||
|
||||
aSetBuffer(cmd++, 0, DMEM_WET_LEFT_CH, DMEM_WET_SCRATCH, bufItem->unk_18 * 2);
|
||||
aResample(cmd++, reverb->resampleFlags, bufItem->unk_16, reverb->unk_38);
|
||||
|
@ -268,29 +274,31 @@ Acmd* func_800DB680(Acmd* cmd, SynthesisReverb* reverb, s16 bufIndex) {
|
|||
return cmd;
|
||||
}
|
||||
|
||||
Acmd* func_800DB828(Acmd* cmd, s32 arg1, SynthesisReverb* reverb, s16 arg3) {
|
||||
ReverbRingBufferItem* item = &reverb->items[reverb->curFrame][arg3];
|
||||
Acmd* func_800DB828(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
ReverbRingBufferItem* item = &reverb->items[reverb->curFrame][updateIndex];
|
||||
s16 offsetA;
|
||||
s16 offsetB;
|
||||
|
||||
item->unk_14 = (item->unk_18 << 0xF) / arg1;
|
||||
item->unk_14 = (item->unk_18 << 0xF) / aiBufLen;
|
||||
offsetA = (item->startPos & 7) * 2;
|
||||
item->unk_16 = (arg1 << 0xF) / item->unk_18;
|
||||
item->unk_16 = (aiBufLen << 0xF) / item->unk_18;
|
||||
offsetB = ALIGN16(offsetA + item->lengthA);
|
||||
cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_TEMP, item->startPos - (offsetA / 2), DEFAULT_LEN_1CH, reverb);
|
||||
if (item->lengthB != 0) {
|
||||
// Ring buffer wrapped
|
||||
cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_TEMP + offsetB, 0, DEFAULT_LEN_1CH - offsetB, reverb);
|
||||
}
|
||||
aSetBuffer(cmd++, 0, DMEM_WET_TEMP + offsetA, DMEM_WET_LEFT_CH, arg1 * 2);
|
||||
aSetBuffer(cmd++, 0, DMEM_WET_TEMP + offsetA, DMEM_WET_LEFT_CH, aiBufLen * 2);
|
||||
aResample(cmd++, reverb->resampleFlags, item->unk_14, reverb->unk_30);
|
||||
aSetBuffer(cmd++, 0, DMEM_WET_TEMP + DEFAULT_LEN_1CH + offsetA, DMEM_WET_RIGHT_CH, arg1 * 2);
|
||||
aSetBuffer(cmd++, 0, DMEM_WET_TEMP + DEFAULT_LEN_1CH + offsetA, DMEM_WET_RIGHT_CH, aiBufLen * 2);
|
||||
aResample(cmd++, reverb->resampleFlags, item->unk_14, reverb->unk_34);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a filter (convolution) to each reverb channel.
|
||||
*/
|
||||
Acmd* AudioSynth_FilterReverb(Acmd* cmd, s32 count, SynthesisReverb* reverb) {
|
||||
// Apply a filter (convolution) to each reverb channel.
|
||||
if (reverb->filterLeft != NULL) {
|
||||
aFilter(cmd++, 2, count, reverb->filterLeft);
|
||||
aFilter(cmd++, reverb->resampleFlags, DMEM_WET_LEFT_CH, reverb->filterLeftState);
|
||||
|
@ -303,14 +311,14 @@ Acmd* AudioSynth_FilterReverb(Acmd* cmd, s32 count, SynthesisReverb* reverb) {
|
|||
return cmd;
|
||||
}
|
||||
|
||||
Acmd* AudioSynth_MaybeMixRingBuffer1(Acmd* cmd, SynthesisReverb* reverb, s32 arg2) {
|
||||
Acmd* AudioSynth_MaybeMixRingBuffer1(Acmd* cmd, SynthesisReverb* reverb, s32 updateIndex) {
|
||||
SynthesisReverb* temp_a3;
|
||||
|
||||
temp_a3 = &gAudioContext.synthesisReverbs[reverb->unk_05];
|
||||
if (temp_a3->downsampleRate == 1) {
|
||||
cmd = AudioSynth_LoadRingBuffer1AtTemp(cmd, temp_a3, arg2);
|
||||
cmd = AudioSynth_LoadRingBuffer1AtTemp(cmd, temp_a3, updateIndex);
|
||||
aMix(cmd++, 0x34, reverb->unk_08, DMEM_WET_LEFT_CH, DMEM_WET_TEMP);
|
||||
cmd = AudioSynth_SaveRingBuffer1AtTemp(cmd, temp_a3, arg2);
|
||||
cmd = AudioSynth_SaveRingBuffer1AtTemp(cmd, temp_a3, updateIndex);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
@ -454,8 +462,8 @@ void AudioSynth_LoadFilterCount(Acmd* cmd, s32 count, s32 addr) {
|
|||
aFilter(cmd, 2, count, addr);
|
||||
}
|
||||
|
||||
Acmd* AudioSynth_LoadRingBuffer1(Acmd* cmd, s32 arg1, SynthesisReverb* reverb, s16 bufIndex) {
|
||||
ReverbRingBufferItem* ringBufferItem = &reverb->items[reverb->curFrame][bufIndex];
|
||||
Acmd* AudioSynth_LoadRingBuffer1(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
ReverbRingBufferItem* ringBufferItem = &reverb->items[reverb->curFrame][updateIndex];
|
||||
|
||||
cmd =
|
||||
AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_LEFT_CH, ringBufferItem->startPos, ringBufferItem->lengthA, reverb);
|
||||
|
@ -468,8 +476,8 @@ Acmd* AudioSynth_LoadRingBuffer1(Acmd* cmd, s32 arg1, SynthesisReverb* reverb, s
|
|||
return cmd;
|
||||
}
|
||||
|
||||
Acmd* AudioSynth_LoadRingBuffer2(Acmd* cmd, s32 arg1, SynthesisReverb* reverb, s16 bufIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items2[reverb->curFrame][bufIndex];
|
||||
Acmd* AudioSynth_LoadRingBuffer2(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items2[reverb->curFrame][updateIndex];
|
||||
|
||||
cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_LEFT_CH, bufItem->startPos, bufItem->lengthA, reverb);
|
||||
if (bufItem->lengthB != 0) {
|
||||
|
@ -496,34 +504,34 @@ Acmd* AudioSynth_SaveBufferOffset(Acmd* cmd, u16 dmem, u16 offset, s32 length, s
|
|||
return cmd;
|
||||
}
|
||||
|
||||
Acmd* AudioSynth_MaybeLoadRingBuffer2(Acmd* cmd, s32 arg1, SynthesisReverb* reverb, s16 bufIndex) {
|
||||
Acmd* AudioSynth_MaybeLoadRingBuffer2(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
if (reverb->downsampleRate == 1) {
|
||||
cmd = AudioSynth_LoadRingBuffer2(cmd, arg1, reverb, bufIndex);
|
||||
cmd = AudioSynth_LoadRingBuffer2(cmd, aiBufLen, reverb, updateIndex);
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
Acmd* func_800DC164(Acmd* cmd, s32 arg1, SynthesisReverb* reverb, s16 arg3) {
|
||||
Acmd* AudioSynth_LoadReverbSamples(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
// Sets DMEM_WET_{LEFT,RIGHT}_CH, clobbers DMEM_TEMP
|
||||
if (reverb->downsampleRate == 1) {
|
||||
if (reverb->unk_18 != 0) {
|
||||
cmd = func_800DB828(cmd, arg1, reverb, arg3);
|
||||
cmd = func_800DB828(cmd, aiBufLen, reverb, updateIndex);
|
||||
} else {
|
||||
cmd = AudioSynth_LoadRingBuffer1(cmd, arg1, reverb, arg3);
|
||||
cmd = AudioSynth_LoadRingBuffer1(cmd, aiBufLen, reverb, updateIndex);
|
||||
}
|
||||
} else {
|
||||
cmd = func_800DB4E4(cmd, arg1, reverb, arg3);
|
||||
cmd = func_800DB4E4(cmd, aiBufLen, reverb, updateIndex);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
Acmd* AudioSynth_SaveReverbSamples(Acmd* cmd, SynthesisReverb* reverb, s16 bufIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][bufIndex];
|
||||
Acmd* AudioSynth_SaveReverbSamples(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][updateIndex];
|
||||
|
||||
if (reverb->downsampleRate == 1) {
|
||||
if (reverb->unk_18 != 0) {
|
||||
cmd = func_800DB680(cmd, reverb, bufIndex);
|
||||
cmd = func_800DB680(cmd, reverb, updateIndex);
|
||||
} else {
|
||||
// Put the oldest samples in the ring buffer into the wet channels
|
||||
cmd = AudioSynth_SaveRingBufferPart(cmd, DMEM_WET_LEFT_CH, bufItem->startPos, bufItem->lengthA, reverb);
|
||||
|
@ -537,15 +545,15 @@ Acmd* AudioSynth_SaveReverbSamples(Acmd* cmd, SynthesisReverb* reverb, s16 bufIn
|
|||
// Downsampling is done later by CPU when RSP is done, therefore we need to have
|
||||
// double buffering. Left and right buffers are adjacent in memory.
|
||||
AudioSynth_SaveBuffer(cmd++, DMEM_WET_LEFT_CH, DEFAULT_LEN_2CH,
|
||||
reverb->items[reverb->curFrame][bufIndex].toDownsampleLeft);
|
||||
reverb->items[reverb->curFrame][updateIndex].toDownsampleLeft);
|
||||
}
|
||||
|
||||
reverb->resampleFlags = 0;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
Acmd* AudioSynth_SaveRingBuffer2(Acmd* cmd, SynthesisReverb* reverb, s16 bufIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items2[reverb->curFrame][bufIndex];
|
||||
Acmd* AudioSynth_SaveRingBuffer2(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) {
|
||||
ReverbRingBufferItem* bufItem = &reverb->items2[reverb->curFrame][updateIndex];
|
||||
|
||||
cmd = AudioSynth_SaveRingBufferPart(cmd, DMEM_WET_LEFT_CH, bufItem->startPos, bufItem->lengthA, reverb);
|
||||
if (bufItem->lengthB != 0) {
|
||||
|
@ -594,24 +602,36 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updat
|
|||
}
|
||||
|
||||
aClearBuffer(cmd++, DMEM_LEFT_CH, DEFAULT_LEN_2CH);
|
||||
|
||||
i = 0;
|
||||
for (reverbIndex = 0; reverbIndex < gAudioContext.numSynthesisReverbs; reverbIndex++) {
|
||||
reverb = &gAudioContext.synthesisReverbs[reverbIndex];
|
||||
useReverb = reverb->useReverb;
|
||||
if (useReverb) {
|
||||
cmd = func_800DC164(cmd, aiBufLen, reverb, updateIndex);
|
||||
aMix(cmd++, 0x34, reverb->unk_0A, DMEM_WET_LEFT_CH, DMEM_LEFT_CH);
|
||||
|
||||
// Loads reverb samples from RDRAM (ringBuffer) into DMEM (DMEM_WET_LEFT_CH)
|
||||
cmd = AudioSynth_LoadReverbSamples(cmd, aiBufLen, reverb, updateIndex);
|
||||
|
||||
// Mixes reverb sample into the main dry channel
|
||||
// reverb->volume is always set to 0x7FFF (audio spec), and DMEM_LEFT_CH is cleared before the loop.
|
||||
// So for the first iteration, this is essentially a DMEMmove from DMEM_WET_LEFT_CH to DMEM_LEFT_CH
|
||||
aMix(cmd++, DEFAULT_LEN_2CH >> 4, reverb->volume, DMEM_WET_LEFT_CH, DMEM_LEFT_CH);
|
||||
|
||||
unk14 = reverb->unk_14;
|
||||
if (unk14) {
|
||||
aDMEMMove(cmd++, DMEM_WET_LEFT_CH, DMEM_WET_TEMP, DEFAULT_LEN_2CH);
|
||||
}
|
||||
|
||||
aMix(cmd++, 0x34, reverb->unk_0C + 0x8000, DMEM_WET_LEFT_CH, DMEM_WET_LEFT_CH);
|
||||
// Decays reverb over time. The (+ 0x8000) here is -100%
|
||||
aMix(cmd++, DEFAULT_LEN_2CH >> 4, reverb->decayRatio + 0x8000, DMEM_WET_LEFT_CH, DMEM_WET_LEFT_CH);
|
||||
|
||||
// Leak reverb between the left and right channels
|
||||
if (reverb->leakRtl != 0 || reverb->leakLtr != 0) {
|
||||
cmd = AudioSynth_LeakReverb(cmd, reverb);
|
||||
}
|
||||
|
||||
if (unk14) {
|
||||
// Saves the wet channel sample from DMEM (DMEM_WET_LEFT_CH) into RDRAM (ringBuffer) for future use
|
||||
cmd = AudioSynth_SaveReverbSamples(cmd, reverb, updateIndex);
|
||||
if (reverb->unk_05 != -1) {
|
||||
cmd = AudioSynth_MaybeMixRingBuffer1(cmd, reverb, updateIndex);
|
||||
|
@ -637,6 +657,8 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updat
|
|||
if (reverb->filterLeft != NULL || reverb->filterRight != NULL) {
|
||||
cmd = AudioSynth_FilterReverb(cmd, aiBufLen * 2, reverb);
|
||||
}
|
||||
|
||||
// Saves the wet channel sample from DMEM (DMEM_WET_LEFT_CH) into RDRAM (ringBuffer) for future use
|
||||
if (unk14) {
|
||||
cmd = AudioSynth_SaveRingBuffer2(cmd, reverb, updateIndex);
|
||||
} else {
|
||||
|
@ -675,7 +697,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
u16 resamplingRateFixedPoint;
|
||||
s32 nSamplesInFirstFrame;
|
||||
s32 nTrailingSamplesToIgnore;
|
||||
s32 phi_a1_2;
|
||||
s32 gain;
|
||||
s32 frameIndex;
|
||||
s32 skipBytes;
|
||||
s32 temp_v1_6;
|
||||
|
@ -835,16 +857,19 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
skipInitialSamples = 16;
|
||||
sampleDataStart = 0;
|
||||
break;
|
||||
|
||||
case CODEC_SMALL_ADPCM:
|
||||
frameSize = 5;
|
||||
skipInitialSamples = 16;
|
||||
sampleDataStart = 0;
|
||||
break;
|
||||
|
||||
case CODEC_S8:
|
||||
frameSize = 16;
|
||||
skipInitialSamples = 16;
|
||||
sampleDataStart = 0;
|
||||
break;
|
||||
|
||||
case CODEC_S16_INMEMORY:
|
||||
AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, (samplesLenAdjusted * 2) + 0x20);
|
||||
flags = A_CONTINUE;
|
||||
|
@ -852,6 +877,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
nSamplesProcessed = samplesLenAdjusted;
|
||||
s5 = samplesLenAdjusted;
|
||||
goto skip;
|
||||
|
||||
case CODEC_S16:
|
||||
AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, (samplesLenAdjusted * 2) + 0x20);
|
||||
flags = A_CONTINUE;
|
||||
|
@ -859,6 +885,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
nSamplesProcessed = samplesLenAdjusted;
|
||||
s5 = samplesLenAdjusted;
|
||||
goto skip;
|
||||
|
||||
case CODEC_REVERB:
|
||||
break;
|
||||
}
|
||||
|
@ -902,6 +929,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
} else {
|
||||
phi_s4 = ALIGN16(s5 + 16);
|
||||
}
|
||||
|
||||
switch (audioFontSample->codec) {
|
||||
case CODEC_ADPCM:
|
||||
aligned = ALIGN16((nFramesToDecode * frameSize) + 0x10);
|
||||
|
@ -910,6 +938,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
nSamplesToDecode * 2);
|
||||
aADPCMdec(cmd++, flags, synthState->synthesisBuffers->adpcmdecState);
|
||||
break;
|
||||
|
||||
case CODEC_SMALL_ADPCM:
|
||||
aligned = ALIGN16((nFramesToDecode * frameSize) + 0x10);
|
||||
addr = DMEM_COMPRESSED_ADPCM_DATA - aligned;
|
||||
|
@ -917,6 +946,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
nSamplesToDecode * 2);
|
||||
aADPCMdec(cmd++, flags | 4, synthState->synthesisBuffers->adpcmdecState);
|
||||
break;
|
||||
|
||||
case CODEC_S8:
|
||||
aligned = ALIGN16((nFramesToDecode * frameSize) + 0x10);
|
||||
addr = DMEM_COMPRESSED_ADPCM_DATA - aligned;
|
||||
|
@ -938,9 +968,11 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
skipBytes = 0x20;
|
||||
s5 = (nSamplesToDecode + 0x10) * 2;
|
||||
break;
|
||||
|
||||
case A_LOOP:
|
||||
s5 = nSamplesInThisIteration * 2 + s5;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (s5 != 0) {
|
||||
s5 = nSamplesInThisIteration * 2 + s5;
|
||||
|
@ -974,6 +1006,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
case 1:
|
||||
noteSamplesDmemAddrBeforeResampling = DMEM_UNCOMPRESSED_NOTE + skipBytes;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switch (curPart) {
|
||||
case 0:
|
||||
|
@ -986,6 +1019,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
samplesLenAdjusted + 0x10);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
AudioSynth_InterL(cmd++, DMEM_UNCOMPRESSED_NOTE + skipBytes,
|
||||
DMEM_TEMP + 0x20 + resampledTempLen, ALIGN8(samplesLenAdjusted / 2));
|
||||
|
@ -1014,12 +1048,13 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
AudioSynth_UnkCmd3(cmd++, DMEM_TEMP, DMEM_TEMP, aiBufLen * 2);
|
||||
}
|
||||
|
||||
phi_a1_2 = noteSubEu->unk_2;
|
||||
if (phi_a1_2 != 0) {
|
||||
if (phi_a1_2 < 0x10) {
|
||||
phi_a1_2 = 0x10;
|
||||
gain = noteSubEu->gain;
|
||||
if (gain != 0) {
|
||||
// A gain of 0x10 (a UQ4.4 number) is equivalent to 1.0 and represents no volume change
|
||||
if (gain < 0x10) {
|
||||
gain = 0x10;
|
||||
}
|
||||
AudioSynth_HiLoGain(cmd++, phi_a1_2, DMEM_TEMP, 0, (aiBufLen * 2) + 0x20);
|
||||
AudioSynth_HiLoGain(cmd++, gain, DMEM_TEMP, 0, (aiBufLen * 2) + 0x20);
|
||||
}
|
||||
|
||||
filter = noteSubEu->filter;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue