Starship/src/audio/audio_synthesis.c
2024-09-17 19:31:14 -03:00

1320 lines
46 KiB
C

#include "sys.h"
#include "sf64audio_provisional.h"
s32 D_80145D40; // unused
// all of these are part of the DFT-related function
f32 D_80145D48[256];
f32 D_80146148[256];
f32 D_80146548[515];
f32 D_80146D54;
f32 D_80146D58;
f32 D_80146D5C;
f32 D_80146D60;
f32 D_80146D64;
f32 D_80146D68;
f32 D_80146D6C;
f32 D_80146D70;
static const char devstr0[] = "Table Remake\n";
static const char devstr1[] = "-------------------Undefined Ctype \n";
static const char devstr2[] = "Error? Limit OVER %d in %d\n";
static const char devstr3[] = "";
static const char devstr4[] = "Get %x %x\n";
static const char devstr5[] = "Break %x %d %d \n";
static const char devstr6[] = "Terminate-Canceled Channel %d,Phase %d\n";
static const char devstr7[] = "S->W\n";
static const char devstr8[] = "W->S\n";
static const char devstr9[] = "S-Resample Pitch %x (old %d -> delay %d)\n";
void func_80009A2C(s32 updateIndex, s32 noteIndex);
void func_80009AAC(s32 updateIndex);
Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synthState, s16* aiBuf, s32 aiBufLen,
Acmd* aList, s32 updateIndex);
Acmd* func_8000A25C(s16* aiBuf, s32 aiBufLen, Acmd* aList, s32 updateIndex);
Acmd* func_800098DC(Acmd* aList, u16 dmem, u16 startPos, s32 size, s32 reverbIndex);
Acmd* func_80009984(Acmd* aList, u16 dmem, u16 startPos, s32 size, s32 reverbIndex);
Acmd* func_80009D78(Acmd* aList, s32 aiBufLen, s16 reverbIndex, s16 updateIndex);
Acmd* func_8000A128(Acmd* aList, s16 reverbIndex, s16 updateIndex);
Acmd* func_8000B3F0(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 numSamplesToLoad);
Acmd* func_8000B480(Acmd* aList, NoteSynthesisState* synthState, s32 size, u16 pitch, u16 inpDmem, u32 resampleFlags);
Acmd* func_8000B51C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 aiBufLen, u16 dmemSrc,
s32 delaySide, s32 flags);
Acmd* func_8000B98C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 size, s32 flags,
s32 delaySide);
void func_800080C0(s32 sampleCount, s32 itemIndex, s32 reverbIndex) {
ReverbRingBufferItem* ringItem;
SynthesisReverb* reverb = &gSynthReverbs[reverbIndex];
s32 temp_lo;
s32 temp_v1_3;
s32 i;
s32 j;
s32 pad1;
s32 pad2;
s32 pad3;
if ((reverb->downsampleRate != 1) && (reverb->framesToIgnore == 0)) {
ringItem = &reverb->items[reverb->curFrame][itemIndex];
osInvalDCache(ringItem->toDownsampleLeft, 0x300);
j = 0;
for (i = 0; i < ringItem->lengthA / 2; i++, j += reverb->downsampleRate) {
reverb->leftRingBuf[ringItem->startPos + i] = ringItem->toDownsampleLeft[j];
reverb->rightRingBuf[ringItem->startPos + i] = ringItem->toDownsampleRight[j];
}
for (i = 0; i < ringItem->lengthB / 2; i++, j += reverb->downsampleRate) {
reverb->leftRingBuf[i] = ringItem->toDownsampleLeft[j];
reverb->rightRingBuf[i] = ringItem->toDownsampleRight[j];
}
}
ringItem = &reverb->items[reverb->curFrame][itemIndex];
temp_lo = sampleCount / reverb->downsampleRate;
temp_v1_3 = reverb->nextRingBufPos + temp_lo - reverb->bufSizePerChan;
if (temp_v1_3 < 0) {
ringItem->lengthA = temp_lo * 2;
ringItem->lengthB = 0;
ringItem->startPos = reverb->nextRingBufPos;
reverb->nextRingBufPos += temp_lo;
} else {
ringItem->lengthA = (temp_lo - temp_v1_3) * 2;
ringItem->lengthB = temp_v1_3 * 2;
ringItem->startPos = reverb->nextRingBufPos;
reverb->nextRingBufPos = temp_v1_3;
}
ringItem->numSamplesAfterDownsampling = temp_lo;
ringItem->chunkLen = sampleCount;
}
void func_80008364(f32* buffer0, f32* buffer1, s32 length, f32* buffer2) {
f32 temp_ft0;
f32 var_fs0;
f32* buff0fromStart;
f32* buf2half2;
f32* buf2half3;
f32* buff1half1;
f32* buff0FromEnd;
f32* buff1half2;
s32 half;
s32 i;
s32 size;
size = 1 << length;
half = size >> 1;
// Initialize buffer 2 if it is the wrong size for this calculation
if (size != (s32) buffer2[0]) {
buf2half2 = &buffer2[half];
buf2half3 = &buf2half2[half];
var_fs0 = 0.0f;
temp_ft0 = D_PI / (f32) (2 * size);
for (i = 0; i < half; i++) {
*buf2half2++ = (__cosf(var_fs0) - __sinf(var_fs0)) * 0.707107f;
*buf2half3++ = (__cosf(var_fs0) + __sinf(var_fs0)) * 0.707107f;
var_fs0 += temp_ft0;
}
}
// reset the buffer pointers
buf2half2 = &buffer2[half];
buf2half3 = &buf2half2[half];
buff1half1 = buffer1;
buff0fromStart = buffer0;
// handle i = 0 case
buffer1[0] = buffer0[0];
buffer1[half] = buffer0[half];
// advance buffer pointers
buf2half2++;
buf2half3++;
buff0fromStart++;
buff0FromEnd = &buffer0[size - 1];
buff1half1++;
buff1half2 = &buffer1[size - 1];
// convert to real amplitudes
for (i = 1; i < half; i++) {
*buff1half1++ = (*buf2half2 * *buff0fromStart) + (*buf2half3 * *buff0FromEnd);
*buff1half2-- = (*buf2half3 * *buff0fromStart) - (*buf2half2 * *buff0FromEnd);
buff0fromStart++;
buf2half3++;
buf2half2++;
buff0FromEnd--;
}
// FFT buffer 1 using buffer 2
func_80008780(buffer1, length, buffer2);
buff0fromStart = buffer0;
buff0FromEnd = &buffer0[size - 1];
buff1half1 = buffer1;
buff1half2 = &buffer1[half];
// Copy even entries of buffer 0 into the first half of buffer 1. Copy odd entries into the second half in reverse
// order
for (i = 0; i < half; i++) {
*buff0fromStart = *buff1half1++;
*buff0FromEnd = *buff1half2++;
buff0fromStart += 2;
buff0FromEnd -= 2;
}
}
// https://decomp.me/scratch/8eyVg
#ifdef NON_MATCHING
void func_80008780(f32* arg0, s32 arg1, f32* arg2) {
s32 length;
s32 spD0;
s32 spCC;
s32 spC8;
s32 var_a0;
s32 spC0;
s32 spBC;
s32 pad;
s32 spB4;
s32 sp58;
s32 sp50;
s32 spA8;
f32 var_fs0;
f32 temp_fa0;
f32 temp_fv1;
f32* temp_a0;
f32* temp_a1;
f32* temp_a2;
f32* temp_a3;
f32* temp_b0;
f32* temp_b1;
f32* temp_b2;
f32* temp_b3;
f32* var_s0;
f32* var_s1;
f32* var_s2;
f32* var_s3;
length = 1 << arg1;
spBC = length * 2;
sp58 = (length / 8) - 1;
switch (length) {
case 1:
break;
case 2:
temp_fa0 = arg0[1];
temp_fv1 = arg0[0];
arg0[0] = (temp_fa0 + temp_fv1) * 0.707107f;
arg0[1] = (temp_fv1 - temp_fa0) * 0.707107f;
break;
case 4:
temp_fv1 = arg0[0];
arg0[0] = (arg0[2] + temp_fv1) / 2.0f;
arg0[2] = (temp_fv1 - arg0[2]) / 2.0f;
temp_fa0 = arg0[1];
arg0[1] = (arg0[3] + temp_fa0) / 2.0f;
arg0[3] = (temp_fa0 - arg0[3]) / 2.0f;
temp_fv1 = arg0[0];
temp_fa0 = arg0[1];
arg0[0] = arg0[1] + temp_fv1;
arg0[1] = arg0[3] + arg0[2];
arg0[3] = arg0[2] - arg0[3];
arg0[2] = temp_fv1 - temp_fa0;
break;
default:
if (length != (s32) *arg2) {
*arg2 = length;
var_s0 = &arg2[1];
var_s1 = &var_s0[sp58];
var_s2 = &var_s1[sp58];
var_s3 = &var_s2[sp58];
var_fs0 = 6.283186f / length;
for (spCC = 0; spCC < sp58; spCC++) {
*var_s0++ = __cosf(var_fs0);
*var_s1++ = __sinf(var_fs0);
*var_s2++ = __cosf(3.0f * var_fs0);
*var_s3++ = __sinf(3.0f * var_fs0);
var_fs0 += 6.283186f / length;
}
}
spC0 = 1;
for (spD0 = 0; spD0 < arg1 - 1; spD0++) {
spA8 = spBC;
spBC >>= 1;
spB4 = spBC >> 3;
sp50 = spBC >> 2;
var_a0 = 1;
do {
for (spCC = var_a0 - 1; spCC < length; spCC += spA8) {
// if (0) { }
temp_a0 = arg0 + spCC;
temp_a1 = temp_a0 + sp50;
temp_a2 = temp_a1 + sp50;
temp_a3 = temp_a2 + sp50;
D_80146D54 = *temp_a0;
*temp_a0 = *temp_a2 + D_80146D54;
D_80146D58 = *temp_a1;
*temp_a1 = *temp_a1 + *temp_a3;
D_80146D5C = *temp_a2;
*temp_a2 = D_80146D54 - D_80146D5C + D_80146D58 - *temp_a3;
*temp_a3 = D_80146D54 - D_80146D5C - D_80146D58 + *temp_a3;
if (sp50 > 1) {
temp_a0 = arg0 + spCC + spB4;
temp_a1 = temp_a0 + sp50;
temp_a2 = temp_a1 + sp50;
temp_a3 = temp_a2 + sp50;
D_80146D54 = *temp_a0;
*temp_a0 = *temp_a2 + D_80146D54;
D_80146D58 = *temp_a1;
*temp_a1 = *temp_a3 + D_80146D58;
*temp_a2 = (D_80146D54 - *temp_a2) * 1.414214f;
*temp_a3 = (D_80146D58 - *temp_a3) * 1.414214f;
var_s0 = &arg2[spC0];
var_s1 = &var_s0[sp58];
var_s2 = &var_s1[sp58];
var_s3 = &var_s2[sp58];
for (spC8 = 1; spC8 < spB4; spC8++) {
temp_a0 = arg0 + spCC + spC8;
temp_a1 = temp_a0 + sp50;
temp_a2 = temp_a1 + sp50;
temp_a3 = temp_a2 + sp50;
temp_b0 = arg0 + spCC + sp50 - spC8;
temp_b1 = temp_b0 + sp50;
temp_b2 = temp_b1 + sp50;
temp_b3 = temp_b2 + sp50;
D_80146D54 = *temp_a0;
D_80146D58 = *temp_a1;
D_80146D5C = *temp_a2;
D_80146D60 = *temp_a3;
D_80146D64 = *temp_b0;
D_80146D68 = *temp_b1;
D_80146D6C = *temp_b2;
D_80146D70 = *temp_b3;
*temp_a0 = D_80146D54 + D_80146D5C;
*temp_a1 = D_80146D58 + D_80146D60;
*temp_a2 = ((D_80146D54 - D_80146D5C + D_80146D64 - D_80146D6C) * *var_s0) +
((D_80146D60 - D_80146D58 + D_80146D68 - D_80146D70) * *var_s1);
*temp_a3 = ((D_80146D54 - D_80146D5C - D_80146D64 + D_80146D6C) * *var_s2) -
((D_80146D60 - D_80146D58 - D_80146D68 + D_80146D70) * *var_s3);
*temp_b0 = D_80146D64 + D_80146D6C;
*temp_b1 = D_80146D68 + D_80146D70;
*temp_b2 = ((D_80146D54 - D_80146D5C + D_80146D64 - D_80146D6C) * *var_s1) -
((D_80146D60 - D_80146D58 + D_80146D68 - D_80146D70) * *var_s0);
*temp_b3 = ((D_80146D54 - D_80146D5C - D_80146D64 + D_80146D6C) * *var_s3) +
((D_80146D60 - D_80146D58 - D_80146D68 + D_80146D70) * *var_s2);
var_s0 += spC0;
var_s1 += spC0;
var_s2 += spC0;
var_s3 += spC0;
}
}
}
var_a0 = ((spA8 * 2) - spBC) + 1;
spA8 *= 4;
} while (var_a0 < length);
spC0 = spC0 * 2;
temp_a0 = arg0;
for (spC8 = 0; spC8 < length; spC8++, temp_a0++) {
*temp_a0 /= 1.414214f;
}
}
var_a0 = 1;
spA8 = 4;
do {
for (spCC = var_a0 - 1; spCC < length; spCC += spA8) {
D_80146D54 = arg0[spCC];
arg0[spCC] = arg0[spCC + 1] + D_80146D54;
arg0[spCC + 1] = D_80146D54 - arg0[spCC + 1];
}
var_a0 = (spA8 * 2) - 1;
spA8 *= 4;
} while (var_a0 < length);
temp_a0 = arg0;
for (spC8 = 0; spC8 < length; spC8++) {
*temp_a0++ /= 1.414214f;
}
spB4 = 1;
temp_a0 = arg0;
for (spC8 = 1; spC8 < length; spC8++) {
if (spC8 < spB4) {
D_80146D54 = arg0[spB4 - 1];
arg0[spB4 - 1] = *temp_a0;
*temp_a0 = D_80146D54;
}
temp_a0++;
spC0 = length >> 1;
while (spC0 < spB4) {
spB4 -= spC0;
spC0 >>= 1;
}
spB4 += spC0;
}
break;
}
}
#else
#pragma GLOBAL_ASM("asm/us/rev1/nonmatchings/audio/audio_synthesis/func_80008780.s")
#endif
// https://decomp.me/scratch/mYlns
#ifdef NON_MATCHING
void func_80009124(s16** arg0) {
s16* var_a1;
s32 temp_a0;
u8 temp_s0;
u8 temp_s1;
s32 temp_t5_4;
s32 temp_v0;
u8 temp_v1;
s32 var_s1;
s32 var_t2;
s32 var_v1;
u16 var_s0;
u32 var_t3;
s32 i;
s32 j;
var_a1 = *arg0;
for (i = 255; i >= 0; i--) {
D_80145D48[i] = 0.0f;
}
var_t3 = *var_a1++ << 0x10;
var_t3 |= *var_a1++;
for (var_t2 = 0; var_t2 != 0x100; var_t2 += 0x40) {
temp_s0 = var_t3 >> 0x18;
var_v1 = var_t2;
var_t3 <<= 8;
temp_v0 = ((temp_s0 >> 4) & 0xF);
temp_a0 = temp_s0 & 0xF;
if (((temp_s0 >> 4) & 0xF) == 0) {
continue;
}
switch (temp_v0) {
case 1:
while (true) {
var_s0 = *var_a1++;
for (var_s1 = 0; var_s1 < 4; var_s1++) {
temp_s1 = (var_s0 >> 0xC) & 0xF;
var_s0 <<= 4;
D_80145D48[var_v1++] = ((temp_s1 & 7) - 4) << temp_a0;
if (temp_s1 >= 8) {
goto case_1_break;
}
}
}
case_1_break:
break;
case 2:
var_s1 = -1;
while (++var_s1 < 16) {
var_s0 = *var_a1++;
for (i = 0; i < 4; i++) {
temp_s1 = (var_s0 >> 0xC) & 0xF;
var_s0 <<= 4;
D_80145D48[var_v1++] = (temp_s1 - 8) << temp_a0;
}
}
break;
case 6:
while (true) {
var_s0 = *var_a1++;
temp_s1 = (var_s0 >> 8) & 0xFF;
D_80145D48[var_v1] = ((temp_s1 & 0x3F) - 0x20) << temp_a0;
if (temp_s1 >> 6 == 0) {
break;
}
var_v1 += temp_s1 >> 6;
temp_s1 = var_s0 & 0xFF;
D_80145D48[var_v1] = ((temp_s1 & 0x3F) - 0x20) << temp_a0;
if (temp_s1 >> 6 == 0) {
break;
}
var_v1 += temp_s1 >> 6;
}
break;
case 3:
while (true) {
var_s0 = *var_a1++;
temp_s1 = (var_s0 >> 8) & 0xFF;
D_80145D48[var_v1++] = ((temp_s1 & 0x7F) - 0x40) << temp_a0;
if (temp_s1 >= 0x80) {
break;
}
temp_s1 = var_s0 & 0xFF;
D_80145D48[var_v1++] = ((temp_s1 & 0x7F) - 0x40) << temp_a0;
if (temp_s1 >= 0x80) {
break;
}
}
break;
case 4:
while (true) {
var_s0 = *var_a1++;
temp_t5_4 = var_s0 >> 0xC;
D_80145D48[var_v1] = ((var_s0 & 0xFFF) - 0x800) << temp_a0;
if (temp_t5_4 == 0) {
break;
}
var_v1 += temp_t5_4;
}
break;
case 5:
while (true) {
var_s0 = *var_a1++;
D_80145D48[var_v1] = ((var_s0 & 0x7FFF) - 0x4000) << temp_a0;
if ((var_s0 >> 0xF) == 1) {
break;
}
var_v1++;
}
break;
}
}
*arg0 = var_a1;
}
#else
void func_80009124(s16** arg0);
#pragma GLOBAL_ASM("asm/us/rev1/nonmatchings/audio/audio_synthesis/func_80009124.s")
#endif
void func_80009504(s16* arg0, UnkStruct_800097A8* arg1) {
s32 i;
if (arg1->unk_0 != NULL) {
arg1->unk_C = arg1->unk_0;
arg1->unk_0 = 0;
}
arg1->unk18 += D_8014C1B4;
while (arg1->unk18 > 0x1000) {
func_80009124(&arg1->unk_C);
arg1->unk18 -= 0x1000;
}
func_80008364(D_80145D48, D_80146148, 8, D_80146548);
for (i = 0; i < 256; i++) {
if (D_80145D48[i] > 32767.0f) {
D_80145D48[i] = 32767.0f;
}
if (D_80145D48[i] < -32767.0f) {
D_80145D48[i] = -32767.0f;
}
}
for (i = 0; i < 0x100; i++, arg0++) {
*arg0 = D_80145D48[i];
}
}
s32 func_8000967C(s32 length, s16* ramAddr, UnkStruct_800097A8* arg2) {
s32 pad;
s32 temp_t0;
s32 i;
s32 var_s1;
s16* temp_t7 = (s16*) arg2->unk_14->ramAddr;
for (i = 0; i < arg2->unk_4; i++) {
ramAddr[i] = temp_t7[i];
}
var_s1 = arg2->unk_4;
temp_t0 = (length - arg2->unk_4 + 0xFF) / 256;
arg2->unk_4 = (temp_t0 * 256) + arg2->unk_4 - length;
for (i = 0; i < temp_t0; i++) {
func_80009504(&ramAddr[var_s1], arg2);
var_s1 += 0x100;
}
for (i = 0; i < arg2->unk_4; i++) {
temp_t7[i] = ramAddr[length + i];
}
return temp_t0;
}
u8* func_800097A8(Sample* sample, s32 length, u32 flags, UnkStruct_800097A8* arg3) {
s32 pad1;
SampleDma* pad2;
SampleDma* sp1C;
if (flags == 1) {
arg3->unk_0 = (s16*) sample->sampleAddr;
arg3->unk_4 = 0;
arg3->unk_8 = 0;
arg3->unk18 = 0;
if (gSampleDmaReuseQueue1RdPos != gSampleDmaReuseQueue1WrPos) {
arg3->unk_14 = &gSampleDmas[gSampleDmaReuseQueue1[gSampleDmaReuseQueue1RdPos++]];
arg3->unk_14->devAddr = -1;
arg3->unk_14->sizeUnused = 0;
}
}
if (gSampleDmaReuseQueue1RdPos != gSampleDmaReuseQueue1WrPos) {
sp1C = &gSampleDmas[gSampleDmaReuseQueue1[gSampleDmaReuseQueue1RdPos++]];
}
if (1) {} //! FAKE
sp1C->ttl = 2;
sp1C->devAddr = (uintptr_t) sample->sampleAddr;
sp1C->sizeUnused = length * 2;
pad2 = arg3->unk_14;
pad2->ttl = 2;
arg3->unk_8 += func_8000967C(length, (s16*) sp1C->ramAddr, arg3);
return sp1C->ramAddr;
}
Acmd* func_800098DC(Acmd* aList, u16 dmem, u16 startPos, s32 size, s32 reverbIndex) {
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(&gSynthReverbs[reverbIndex].leftRingBuf[startPos]), dmem, size);
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(&gSynthReverbs[reverbIndex].rightRingBuf[startPos]), dmem + 0x180, size);
return aList;
}
Acmd* func_80009984(Acmd* aList, u16 dmem, u16 startPos, s32 size, s32 reverbIndex) {
aSaveBuffer(aList++, dmem, OS_K0_TO_PHYSICAL(&gSynthReverbs[reverbIndex].leftRingBuf[startPos]), size);
aSaveBuffer(aList++, dmem + 0x180, OS_K0_TO_PHYSICAL(&gSynthReverbs[reverbIndex].rightRingBuf[startPos]), size);
return aList;
}
void func_80009A2C(s32 updateIndex, s32 noteIndex) {
NoteSubEu* noteSubEu;
s32 i;
for (i = updateIndex + 1; i < gAudioBufferParams.ticksPerUpdate; i++) {
if (!gNoteSubsEu[(gNumNotes * i) + noteIndex].bitField0.needsInit) {
gNoteSubsEu[(gNumNotes * i) + noteIndex].bitField0.enabled = false;
} else {
break;
}
}
}
void func_80009AAC(s32 updateIndex) {
NoteSubEu* subEu;
NoteSubEu* subEu2;
s32 i;
for (i = 0; i < gNumNotes; i++) {
subEu = &gNotes[i].noteSubEu;
subEu2 = &gNoteSubsEu[gNumNotes * updateIndex + i];
if (subEu->bitField0.enabled) {
*subEu2 = *subEu;
subEu->bitField0.needsInit = false;
} else {
subEu2->bitField0.enabled = false;
}
}
}
Acmd* func_80009B64(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLen) {
Acmd* aCmdPtr;
s32* aiBufPtr;
s32 chunkLen;
s32 i;
s32 j;
aCmdPtr = aList;
for (i = gAudioBufferParams.ticksPerUpdate; i > 0; i--) {
func_8001678C(i - 1);
func_80009AAC(gAudioBufferParams.ticksPerUpdate - i);
}
aiBufPtr = (s32*) aiBufStart;
for (i = gAudioBufferParams.ticksPerUpdate; i > 0; i--) {
if (i == 1) {
chunkLen = aiBufLen;
} else if ((aiBufLen / i) >= gAudioBufferParams.samplesPerTickMax) {
chunkLen = gAudioBufferParams.samplesPerTickMax;
} else if (gAudioBufferParams.samplesPerTickMin >= (aiBufLen / i)) {
chunkLen = gAudioBufferParams.samplesPerTickMin;
} else {
chunkLen = gAudioBufferParams.samplesPerTick;
}
for (j = 0; j < gNumSynthReverbs; j++) {
if (gSynthReverbs[j].useReverb) {
func_800080C0(chunkLen, gAudioBufferParams.ticksPerUpdate - i, j);
}
}
aCmdPtr = func_8000A25C((s16*) aiBufPtr, chunkLen, aCmdPtr, gAudioBufferParams.ticksPerUpdate - i);
aiBufLen -= chunkLen;
aiBufPtr += chunkLen;
}
for (j = 0; j < gNumSynthReverbs; j++) {
if (gSynthReverbs[j].framesToIgnore != 0) {
gSynthReverbs[j].framesToIgnore--;
}
gSynthReverbs[j].curFrame ^= 1;
}
*cmdCount = aCmdPtr - aList;
return aCmdPtr;
}
Acmd* func_80009D78(Acmd* aList, s32 aiBufLen, s16 reverbIndex, s16 updateIndex) {
ReverbRingBufferItem* sp64 = &gSynthReverbs[reverbIndex].items[gSynthReverbs[reverbIndex].curFrame][updateIndex];
s16 sp62;
s16 sp60;
aClearBuffer(aList++, 0xC90, 0x300);
if (gSynthReverbs[reverbIndex].downsampleRate == 1) {
aList = func_800098DC(aList, 0xC90, sp64->startPos, sp64->lengthA, reverbIndex);
if (sp64->lengthB != 0) {
aList = func_800098DC(aList, sp64->lengthA + 0xC90, 0, sp64->lengthB, reverbIndex);
}
aAddMixer(aList++, 0x300, 0xC90, 0x990, 0x7FFF);
aMix(aList++, 0x30, gSynthReverbs[reverbIndex].decayRatio + 0x8000, 0xC90, 0xC90);
} else {
sp62 = (sp64->startPos & 7) * 2;
sp60 = ALIGN16(sp62 + sp64->lengthA);
aList = func_800098DC(aList, 0x470, sp64->startPos - (sp62 / 2), 0x180, reverbIndex);
if (sp64->lengthB != 0) {
aList = func_800098DC(aList, sp60 + 0x470, 0, 0x180 - sp60, reverbIndex);
}
aSetBuffer(aList++, 0, sp62 + 0x470, 0xC90, aiBufLen * 2);
aResample(aList++, gSynthReverbs[reverbIndex].resampleFlags, gSynthReverbs[reverbIndex].unk_0A,
OS_K0_TO_PHYSICAL(gSynthReverbs[reverbIndex].unk_30));
aSetBuffer(aList++, 0, sp62 + 0x5F0, 0xE10, aiBufLen * 2);
aResample(aList++, gSynthReverbs[reverbIndex].resampleFlags, gSynthReverbs[reverbIndex].unk_0A,
OS_K0_TO_PHYSICAL(gSynthReverbs[reverbIndex].unk_34));
aAddMixer(aList++, 0x300, 0xC90, 0x990, 0x7FFF);
aMix(aList++, 0x30, gSynthReverbs[reverbIndex].decayRatio + 0x8000, 0xC90, 0xC90);
}
if ((gSynthReverbs[reverbIndex].leakRtL != 0) || (gSynthReverbs[reverbIndex].leakLtR != 0)) {
aDMEMMove(aList++, 0xC90, 0x470, 0x180);
aMix(aList++, 0x18, gSynthReverbs[reverbIndex].leakRtL, 0xE10, 0xC90);
aMix(aList++, 0x18, gSynthReverbs[reverbIndex].leakLtR, 0x470, 0xE10);
}
return aList;
}
Acmd* func_8000A128(Acmd* aList, s16 reverbIndex, s16 updateIndex) {
ReverbRingBufferItem* sp24;
sp24 = &gSynthReverbs[reverbIndex].items[gSynthReverbs[reverbIndex].curFrame][updateIndex];
switch (gSynthReverbs[reverbIndex].downsampleRate) {
case 1:
aList = func_80009984(aList, 0xC90, sp24->startPos, sp24->lengthA, reverbIndex);
if (sp24->lengthB != 0) {
aList = func_80009984(aList, sp24->lengthA + 0xC90, 0, sp24->lengthB, reverbIndex);
}
break;
default:
aSaveBuffer(aList++, 0xC90,
OS_K0_TO_PHYSICAL(gSynthReverbs[reverbIndex]
.items[gSynthReverbs[reverbIndex].curFrame][updateIndex]
.toDownsampleLeft),
0x300);
gSynthReverbs[reverbIndex].resampleFlags = 0;
break;
}
return aList;
}
Acmd* func_8000A25C(s16* aiBuf, s32 aiBufLen, Acmd* aList, s32 updateIndex) {
u8 sp84[0x3C];
NoteSubEu* temp_v0;
s16 var_s2;
s16 i;
s32 j;
var_s2 = 0;
if (gNumSynthReverbs == 0) {
if (gSynthReverbs[i].useReverb) {} // fake?
for (j = 0; j < gNumNotes; j++) {
if (gNoteSubsEu[gNumNotes * updateIndex + j].bitField0.enabled) {
sp84[var_s2++] = j;
}
}
} else {
for (i = 0; i < gNumSynthReverbs; i++) {
for (j = 0; j < gNumNotes; j++) {
temp_v0 = &gNoteSubsEu[gNumNotes * updateIndex + j];
if (temp_v0->bitField0.enabled && (temp_v0->bitField1.reverbIndex == i)) {
sp84[var_s2++] = j;
}
}
}
for (j = 0; j < gNumNotes; j++) {
temp_v0 = &gNoteSubsEu[gNumNotes * updateIndex + j];
if (temp_v0->bitField0.enabled && (temp_v0->bitField1.reverbIndex >= gNumSynthReverbs)) {
sp84[var_s2++] = j;
}
}
}
aClearBuffer(aList++, 0x990, 0x300);
j = 0;
for (i = 0; i < gNumSynthReverbs; i++) {
D_8014C1B2 = gSynthReverbs[i].useReverb;
if (D_8014C1B2) {
aList = func_80009D78(aList, aiBufLen, i, updateIndex);
}
while (j < var_s2) {
if (i != gNoteSubsEu[updateIndex * gNumNotes + sp84[j]].bitField1.reverbIndex) {
break;
}
aList = func_8000A700(sp84[j], &gNoteSubsEu[updateIndex * gNumNotes + sp84[j]],
&gNotes[sp84[j]].synthesisState, aiBuf, aiBufLen, aList, updateIndex);
j++;
}
if (gSynthReverbs[i].useReverb) {
aList = func_8000A128(aList, i, updateIndex);
}
}
while (j < var_s2) {
aList = func_8000A700(sp84[j], &gNoteSubsEu[updateIndex * gNumNotes + sp84[j]], &gNotes[sp84[j]].synthesisState,
aiBuf, aiBufLen, aList, updateIndex);
j++;
}
j = aiBufLen * 2;
aSetBuffer(aList++, 0, 0, 0x450, j);
aInterleave(aList++, 0, 0x990, 0xB10, 0);
aSaveBuffer(aList++, 0x450, OS_K0_TO_PHYSICAL(aiBuf), j * 2);
return aList;
}
// https://decomp.me/scratch/RgX4r
#ifdef NON_MATCHING
Acmd* func_8000A700(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synthState, s16* aiBuf, s32 aiBufLen,
Acmd* aList, s32 updateIndex) {
s32 pad11C;
s32 pad118;
s32 pad114;
Sample* bookSample; // sp110
AdpcmLoop* loopInfo; // sp10C
void* currentBook; // sp108
s32 pad104;
s32 pad100;
s32 noteFinished; // spFC
u32 restart; // spF8
s32 flags; // spF4
u16 resampleRateFixedPoint; // spF2
s32 nSamplesToLoad; // spEC
s32 padE8;
s32 padE4;
s32 padE0;
s32 skipBytes; // spDC
s32 padD8;
s32 padD4;
s32 padD0;
u32 sampleAddr; // spCC
s32 padC8;
s32 samplesLenAdjusted; // spC4
s32 nAdpcmSamplesProcessed; // spC0
u32 endPos; // spBC
s32 nSamplesToProcess; // spB8
s32 padB4;
s32 padB0;
s32 padAC;
s32 padA8;
s32 padA4;
s32 nTrailingSamplesToIgnore; // spA0
s32 pad9C;
s32 pad98;
s32 pad94;
s32 frameSize; // sp90
s32 pad8C;
s32 skipInitialSamples; // sp88
s32 sampleDmaStart; // sp84
s32 pad80;
s32 nParts; // sp7C
s32 curPart; // sp78
s32 nSamplesInThisIteration;
s32 sampleDataStartPad;
s32 resampledTempLen; // sp6C
u16 noteSamplesDmemAddrBeforeResampling; // sp6A
s32 samplesRemaining;
s32 frameIndex;
s32 sampleDataOffset;
Note* note; // sp58
u16 sp56; // sp56
s32 nSamplesInFirstFrame;
s32 delaySide;
s32 nSamplesToDecode;
s32 nFramesToDecode;
s32 nFirstFrameSamplesToIgnore;
s32 s5;
u32 sampleslenFixedPoint;
u8* sampleData;
s32 temp;
s32 temp2;
u32 nEntries;
s32 aligned;
s32 align2;
u16 addr;
currentBook = NULL;
note = &gNotes[noteIndex];
flags = 0;
if (noteSub->bitField0.needsInit == 1) {
flags = 1;
synthState->restart = 0;
synthState->samplePosInt = 0;
synthState->samplePosFrac = 0;
synthState->curVolLeft = 0;
synthState->curVolRight = 0;
synthState->prevHaasEffectLeftDelaySize = 0;
synthState->prevHaasEffectRightDelaySize = 0;
synthState->numParts = 0;
note->noteSubEu.bitField0.finished = 0;
}
resampleRateFixedPoint = noteSub->resampleRate;
nParts = noteSub->bitField1.hasTwoParts + 1;
sampleslenFixedPoint = (resampleRateFixedPoint * aiBufLen * 2) + synthState->samplePosFrac;
nSamplesToLoad = (sampleslenFixedPoint) >> 0x10;
synthState->samplePosFrac = sampleslenFixedPoint & 0xFFFF;
if ((synthState->numParts == 1) && (nParts == 2)) {
nSamplesToLoad += 2;
sp56 = 2;
} else if ((synthState->numParts == 2) && (nParts == 1)) {
nSamplesToLoad -= 4;
sp56 = 4;
} else {
sp56 = 0;
}
synthState->numParts = nParts;
if (noteSub->bitField1.isSyntheticWave) {
aList = func_8000B3F0(aList, noteSub, synthState, nSamplesToLoad);
noteSamplesDmemAddrBeforeResampling = (synthState->samplePosInt * 2) + 0x5F0;
synthState->samplePosInt += nSamplesToLoad;
} else {
bookSample = *(Sample**) noteSub->waveSampleAddr;
loopInfo = bookSample->loop;
endPos = loopInfo->end;
sampleAddr = bookSample->sampleAddr;
resampledTempLen = 0;
for (curPart = 0; curPart < nParts; curPart++) {
nAdpcmSamplesProcessed = 0;
s5 = 0;
if (nParts == 1) {
samplesLenAdjusted = nSamplesToLoad;
} else if (nSamplesToLoad & 1) {
samplesLenAdjusted = (nSamplesToLoad & ~1) + (curPart * 2);
} else {
samplesLenAdjusted = nSamplesToLoad;
}
if ((bookSample->codec == 0) && (currentBook != bookSample->book->book)) {
switch (noteSub->bitField1.bookOffset) {
case 1:
currentBook = &gD_800DD200[1];
break;
case 2:
currentBook = &gD_800DD200[2];
break;
default:
case 3:
currentBook = bookSample->book->book;
break;
}
nEntries = 16 * bookSample->book->order * bookSample->book->numPredictors;
aLoadADPCM(aList++, nEntries, OS_K0_TO_PHYSICAL(currentBook));
}
while (nAdpcmSamplesProcessed != samplesLenAdjusted) {
restart = 0;
noteFinished = 0;
samplesRemaining = endPos - synthState->samplePosInt;
nSamplesToProcess = samplesLenAdjusted - nAdpcmSamplesProcessed;
nFirstFrameSamplesToIgnore = synthState->samplePosInt & 0xF;
if ((nFirstFrameSamplesToIgnore == 0) && !synthState->restart) {
nFirstFrameSamplesToIgnore = 0x10;
}
nSamplesInFirstFrame = 0x10 - nFirstFrameSamplesToIgnore;
if (nSamplesToProcess < samplesRemaining) {
nFramesToDecode = (nSamplesToProcess - nSamplesInFirstFrame + 0xF) / 16;
nSamplesToDecode = nFramesToDecode * 0x10;
// if(1) {}
nTrailingSamplesToIgnore = (nSamplesInFirstFrame + nSamplesToDecode) - nSamplesToProcess;
} else {
nSamplesToDecode = samplesRemaining - nSamplesInFirstFrame;
nTrailingSamplesToIgnore = 0;
if (nSamplesToDecode <= 0) {
nSamplesToDecode = 0;
nSamplesInFirstFrame = samplesRemaining;
}
nFramesToDecode = (nSamplesToDecode + 0xF) / 16;
if (loopInfo->count != 0) {
restart = 1;
} else {
noteFinished = 1;
}
}
switch (bookSample->codec) {
case 0:
frameSize = 9;
skipInitialSamples = 0x10;
sampleDmaStart = 0;
break;
case 1:
frameSize = 0x10;
skipInitialSamples = 0x10;
sampleDmaStart = 0;
break;
case 2:
temp =
func_800097A8(bookSample, samplesLenAdjusted, flags, &synthState->synthesisBuffers->unk_40);
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(temp), 0x5F0, (samplesLenAdjusted + 0x10) * 2);
s5 = samplesLenAdjusted;
nAdpcmSamplesProcessed = samplesLenAdjusted;
skipBytes = 0;
goto skip;
}
aligned = ALIGN16(nFramesToDecode * frameSize + 0x10);
addr = 0x990 - aligned;
if (nFramesToDecode != 0) {
frameIndex = (synthState->samplePosInt + skipInitialSamples - nFirstFrameSamplesToIgnore) / 16;
sampleDataOffset = frameIndex * frameSize;
if (bookSample->medium == 0) {
sampleData = sampleDmaStart + sampleDataOffset + sampleAddr;
} else {
sampleData = AudioLoad_DmaSampleData(sampleDmaStart + sampleDataOffset + sampleAddr, aligned,
flags, &synthState->sampleDmaIndex, bookSample->medium);
}
// if (1){}
sampleDataStartPad = (u32) sampleData & 0xF;
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(sampleData - sampleDataStartPad), addr, aligned);
} else {
nSamplesToDecode = 0;
sampleDataStartPad = 0;
}
if (synthState->restart) {
aSetLoop(aList++, OS_K0_TO_PHYSICAL(bookSample->loop->predictorState));
flags = 2;
synthState->restart = 0;
}
nSamplesInThisIteration = nSamplesToDecode + nSamplesInFirstFrame - nTrailingSamplesToIgnore;
if (nAdpcmSamplesProcessed == 0) {
switch (bookSample->codec) {
case 0:
aSetBuffer(aList++, 0, addr + sampleDataStartPad, 0x5F0, nSamplesToDecode * 2);
aADPCMdec(aList++, flags, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers));
break;
case 1:
aSetBuffer(aList++, 0, addr + sampleDataStartPad, 0x5F0, nSamplesToDecode * 2);
aS8Dec(aList++, flags, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers));
break;
}
skipBytes = nFirstFrameSamplesToIgnore * 2;
} else {
// if (1) {}
align2 = ALIGN16(s5 + 0x10);
switch (bookSample->codec) {
case 0:
aSetBuffer(aList++, 0, addr + sampleDataStartPad, align2 + 0x5F0, nSamplesToDecode * 2);
aADPCMdec(aList++, flags, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers));
break;
case 1:
aSetBuffer(aList++, 0, addr + sampleDataStartPad, align2 + 0x5F0, nSamplesToDecode * 2);
aS8Dec(aList++, flags, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers));
break;
}
aDMEMMove(aList++, (align2 + (nFirstFrameSamplesToIgnore * 2) + 0x5F0), s5 + 0x5F0,
nSamplesInThisIteration * 2);
}
nAdpcmSamplesProcessed += nSamplesInThisIteration;
switch (flags) {
case 1:
skipBytes = 0x20;
s5 = (nSamplesToDecode + 0x10) * 2;
break;
case 2:
// if(1) {}
s5 = nSamplesInThisIteration * 2 + s5;
break;
default:
if (s5 != 0) {
s5 = nSamplesInThisIteration * 2 + s5;
} else {
// if (1) { }
s5 = (nFirstFrameSamplesToIgnore + nSamplesInThisIteration) * 2;
}
break;
}
skip:
flags = 0;
// goto dummy_label_147574; dummy_label_147574: ;
if (noteFinished) {
aClearBuffer(aList++, s5 + 0x5F0, (samplesLenAdjusted - nAdpcmSamplesProcessed) * 2);
noteSub->bitField0.finished = 1;
note->noteSubEu.bitField0.finished = 1;
func_80009A2C(updateIndex, noteIndex);
break;
}
if (restart) {
synthState->restart = 1;
synthState->samplePosInt = loopInfo->start;
} else {
synthState->samplePosInt += nSamplesToProcess;
}
}
switch (nParts) {
case 1:
noteSamplesDmemAddrBeforeResampling = skipBytes + 0x5F0;
break;
case 2:
switch (curPart) {
case 0:
aInterl(aList++, skipBytes + 0x5F0, 0x470, ALIGN8(samplesLenAdjusted / 2));
resampledTempLen = samplesLenAdjusted;
noteSamplesDmemAddrBeforeResampling = 0x470;
if (noteSub->bitField0.finished) {
aClearBuffer(aList++, resampledTempLen + noteSamplesDmemAddrBeforeResampling,
samplesLenAdjusted + 0x10);
}
break;
case 1:
aInterl(aList++, skipBytes + 0x5F0, resampledTempLen + 0x470,
ALIGN8(samplesLenAdjusted / 2));
break;
}
break;
}
if (noteSub->bitField0.finished) {
break;
}
}
}
flags = 0;
if (noteSub->bitField0.needsInit == 1) {
flags = 1;
noteSub->bitField0.needsInit = 0;
}
flags = sp56 | flags;
aList = func_8000B480(aList, synthState, aiBufLen * 2, resampleRateFixedPoint, noteSamplesDmemAddrBeforeResampling,
flags);
if (flags & 1) {
flags = 1;
}
if (noteSub->bitField1.bookOffset == 3) {
aUnkCmd19(aList++, 0, aiBufLen * 2, 0x450, 0x450);
}
temp2 = noteSub->gain;
if (temp2 != 0) {
if (temp2 < 0x10) {
temp2 = 0x10;
}
aHiLoGain(aList++, temp2, (aiBufLen + 0x10) * 2, 0x450, 0);
}
if ((noteSub->leftDelaySize != 0) || (synthState->prevHaasEffectLeftDelaySize != 0)) {
delaySide = 1;
} else if ((noteSub->rightDelaySize != 0) || (synthState->prevHaasEffectRightDelaySize != 0)) {
delaySide = 2;
} else {
delaySide = 0;
}
aList = func_8000B51C(aList, noteSub, synthState, aiBufLen, 0x450, delaySide, flags);
// if(restart) {}
if (noteSub->bitField0.usesHeadsetPanEffects) {
if (!(flags & 1)) {
flags = 0;
}
aList = func_8000B98C(aList, noteSub, synthState, aiBufLen * 2, flags, delaySide);
}
return aList;
}
#else
#pragma GLOBAL_ASM("asm/us/rev1/nonmatchings/audio/audio_synthesis/func_8000A700.s")
#endif
Acmd* func_8000B3F0(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 numSamplesToLoad) {
s32 temp_v1;
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(noteSub->waveSampleAddr), 0x5F0, 0x80);
synthState->samplePosInt &= 0x3F;
temp_v1 = 0x40 - synthState->samplePosInt;
if (temp_v1 < numSamplesToLoad) {
if ((((numSamplesToLoad - temp_v1) + 0x3F) / 64) != 0) {
aDuplicate(aList++, ((numSamplesToLoad - temp_v1) + 0x3F) / 64, 0x5F0, 0x670);
}
}
return aList;
}
Acmd* func_8000B480(Acmd* aList, NoteSynthesisState* synthState, s32 size, u16 pitch, u16 inpDmem, u32 resampleFlags) {
if (pitch == 0) {
aClearBuffer(aList++, 0x450, size);
} else {
aSetBuffer(aList++, 0, inpDmem, 0x450, size);
aResample(aList++, resampleFlags, pitch, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers->finalResampleState));
}
return aList;
}
Acmd* func_8000B51C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 aiBufLen, u16 dmemSrc,
s32 delaySide, s32 flags) {
s16 var_a2;
s16 var_a3;
s16 var_t0;
u16 temp_t7;
u16 temp_t9;
u16 temp_t1;
u16 temp_t2;
s32 temp_a1;
s32 temp = 0;
temp_t1 = synthState->curVolLeft;
temp_t2 = synthState->curVolRight;
temp_t7 = noteSub->panVolLeft;
temp_t9 = noteSub->panVolRight;
temp_t7 <<= 4;
temp_t9 <<= 4;
if (temp_t7 != temp_t1) {
var_t0 = (temp_t7 - temp_t1) / (aiBufLen >> 3);
} else {
var_t0 = 0;
}
if (temp_t9 != temp_t2) {
var_a3 = (temp_t9 - temp_t2) / (aiBufLen >> 3);
} else {
var_a3 = 0;
}
temp_a1 = synthState->reverbVol;
if (noteSub->reverb != temp_a1) {
temp = (((noteSub->reverb & 0x7F) - (temp_a1 & 0x7F)) << 8);
var_a2 = temp / (aiBufLen >> 3);
synthState->reverbVol = noteSub->reverb;
} else {
var_a2 = 0;
}
synthState->curVolLeft = temp_t1 + (var_t0 * (aiBufLen >> 3));
synthState->curVolRight = temp_t2 + (var_a3 * (aiBufLen >> 3));
if (noteSub->bitField0.usesHeadsetPanEffects) {
aClearBuffer(aList++, 0x650, 0x180);
aEnvSetup1(aList++, (temp_a1 & 0x7F), var_a2, var_t0, var_a3);
aEnvSetup2(aList++, temp_t1, temp_t2);
switch (delaySide) {
case 1:
aEnvMixer(aList++, dmemSrc, aiBufLen, 0, 0, ((temp_a1 & 0x80) >> 7),
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, 0x65B1C9E1, 0);
break;
case 2:
aEnvMixer(aList++, dmemSrc, aiBufLen, 0, 0, ((temp_a1 & 0x80) >> 7),
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, 0x9965C9E1, 0);
break;
default:
aEnvMixer(aList++, dmemSrc, aiBufLen, 0, 0, ((temp_a1 & 0x80) >> 7),
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, 0x99B1C9E1, 0);
break;
}
} else {
aEnvSetup1(aList++, (temp_a1 & 0x7F), var_a2, var_t0, var_a3);
aEnvSetup2(aList++, temp_t1, temp_t2);
aEnvMixer(aList++, dmemSrc, aiBufLen, 0, 0, ((temp_a1 & 0x80) >> 7), noteSub->bitField0.stereoStrongRight,
noteSub->bitField0.stereoStrongLeft, 0x99B1C9E1, 0);
}
return aList;
}
Acmd* func_8000B98C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 size, s32 flags,
s32 delaySide) {
u16 var_t0;
u8 var_a1;
u8 var_v1;
u16 temp;
switch (delaySide) {
case 1:
var_t0 = 0x990;
var_a1 = noteSub->leftDelaySize;
synthState->prevHaasEffectRightDelaySize = 0;
var_v1 = synthState->prevHaasEffectLeftDelaySize;
synthState->prevHaasEffectLeftDelaySize = var_a1;
break;
case 2:
var_t0 = 0xB10;
var_a1 = noteSub->rightDelaySize;
synthState->prevHaasEffectLeftDelaySize = 0;
var_v1 = synthState->prevHaasEffectRightDelaySize;
synthState->prevHaasEffectRightDelaySize = var_a1;
break;
default:
return aList;
}
if (flags != 1) {
if (var_a1 != var_v1) {
temp = (((size << 0xF) / 2) - 1) / ((size + var_a1 - var_v1 - 2) / 2);
aSetBuffer(aList++, 0, 0x650, 0x450, size + var_a1 - var_v1);
aResampleZoh(aList++, temp, 0);
} else {
aDMEMMove(aList++, 0x650, 0x450, size);
}
if (var_v1 != 0) {
aLoadBuffer(aList++, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers->panSamplesBuffer), 0x650,
ALIGN16(var_v1));
aDMEMMove(aList++, 0x450, var_v1 + 0x650, size + var_a1 - var_v1);
} else {
aDMEMMove(aList++, 0x450, 0x650, size + var_a1);
}
} else {
aDMEMMove(aList++, 0x650, 0x450, size);
aClearBuffer(aList++, 0x650, var_a1);
aDMEMMove(aList++, 0x450, var_a1 + 0x650, size);
}
if (var_a1) {
aSaveBuffer(aList++, size + 0x650, OS_K0_TO_PHYSICAL(synthState->synthesisBuffers->panSamplesBuffer),
ALIGN16(var_a1));
}
aAddMixer(aList++, ALIGN64(size), 0x650, var_t0, 0x7FFF);
return aList;
}