mirror of
https://github.com/DaedalusX64/daedalus.git
synced 2025-04-02 10:21:48 -04:00
358 lines
11 KiB
C++
358 lines
11 KiB
C++
#include "Base/Types.h"
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include "Utility/MathUtil.h"
|
|
#include "Core/Memory.h"
|
|
#include "Debug/DBGConsole.h"
|
|
#include "HLEAudio/HLEAudioInternal.h"
|
|
#include "HLEAudio/HLEAudioState.h"
|
|
|
|
extern bool isMKABI;
|
|
extern bool isZeldaABI;
|
|
|
|
static u32 gEnv_t3 = 0, gEnv_s5 = 0, gEnv_s6 = 0;
|
|
static u16 env[8];
|
|
|
|
inline u16 Sample_Mask(u32 x) { return (u16)(x & 0xffff); }
|
|
|
|
void ENVSETUP1(AudioHLECommand command) {
|
|
// fprintf (dfile, "ENVSETUP1: cmd0 = %08X, cmd1 = %08X\n", command.cmd0,command.cmd1);
|
|
gEnv_t3 = command.cmd0 & 0xFFFF;
|
|
u32 tmp = (command.cmd0 >> 0x8) & 0xFF00;
|
|
env[4] = Sample_Mask(tmp);
|
|
env[5] = Sample_Mask(tmp + gEnv_t3);
|
|
gEnv_s5 = command.cmd1 >> 0x10;
|
|
gEnv_s6 = command.cmd1 & 0xFFFF;
|
|
// fprintf (dfile, " gEnv_t3 = %X / gEnv_s5 = %X / gEnv_s6 = %X / env[4] = %X
|
|
// / env[5] = %X\n", gEnv_t3, gEnv_s5, gEnv_s6, env[4], env[5]);
|
|
}
|
|
|
|
void ENVSETUP2(AudioHLECommand command) {
|
|
// fprintf (dfile, "ENVSETUP2: cmd0 = %08X, cmd1 = %08X\n", command.cmd0,
|
|
// command.cmd1);
|
|
u32 tmp1 = (command.cmd1 >> 0x10);
|
|
env[0] = Sample_Mask(tmp1);
|
|
env[1] = Sample_Mask(tmp1 + gEnv_s5);
|
|
|
|
u32 tmp2 = command.cmd1 & 0xffff;
|
|
env[2] = Sample_Mask(tmp2);
|
|
env[3] = Sample_Mask(tmp2 + gEnv_s6);
|
|
// fprintf (dfile, " env[0] = %X / env[1] = %X / env[2] = %X / env[3] =
|
|
// %X\n", env[0], env[1], env[2], env[3]);
|
|
}
|
|
|
|
void ENVSETUP3(AudioHLECommand command [[maybe_unused]]) {
|
|
// Not implemented
|
|
}
|
|
|
|
void ENVMIXER(AudioHLECommand command) {
|
|
// static int envmixcnt = 0;
|
|
u8 flags(command.Abi1EnvMixer.Flags);
|
|
u32 address(
|
|
command.Abi1EnvMixer
|
|
.Address + gAudioHLEState.Segments[(command.cmd1>>24)&0xf]);
|
|
|
|
gAudioHLEState.EnvMixer(flags, address);
|
|
}
|
|
|
|
void ENVMIXER_GE(AudioHLECommand command [[maybe_unused]]) {
|
|
// Not implemented
|
|
}
|
|
|
|
void ENVMIXER2(AudioHLECommand command) {
|
|
// fprintf (dfile, "ENVMIXER: cmd0 = %08X, cmd1 = %08X\n", command.cmd0,
|
|
// command.cmd1);
|
|
s16 vec9, vec10;
|
|
|
|
s16 *buffs3 =
|
|
(s16 *)(gAudioHLEState.Buffer + ((command.cmd0 >> 0x0c) & 0x0ff0));
|
|
s16 *bufft6 =
|
|
(s16 *)(gAudioHLEState.Buffer + ((command.cmd1 >> 0x14) & 0x0ff0));
|
|
s16 *bufft7 =
|
|
(s16 *)(gAudioHLEState.Buffer + ((command.cmd1 >> 0x0c) & 0x0ff0));
|
|
s16 *buffs0 =
|
|
(s16 *)(gAudioHLEState.Buffer + ((command.cmd1 >> 0x04) & 0x0ff0));
|
|
s16 *buffs1 =
|
|
(s16 *)(gAudioHLEState.Buffer + ((command.cmd1 << 0x04) & 0x0ff0));
|
|
|
|
s16 v2[8];
|
|
v2[0] = 0 - (s16)((command.cmd0 & 0x2) >> 1);
|
|
v2[1] = 0 - (s16)((command.cmd0 & 0x1));
|
|
v2[2] = 0 - (s16)((command.cmd0 & 0x8) >> 1);
|
|
v2[3] = 0 - (s16)((command.cmd0 & 0x4) >> 1);
|
|
|
|
s32 count = (command.cmd0 >> 8) & 0xff;
|
|
|
|
u32 adder;
|
|
if (!isMKABI) {
|
|
gEnv_s5 *= 2;
|
|
gEnv_s6 *= 2;
|
|
gEnv_t3 *= 2;
|
|
adder = 0x10;
|
|
} else {
|
|
command.cmd0 = 0;
|
|
adder = 0x8;
|
|
gEnv_t3 = 0;
|
|
}
|
|
|
|
while (count > 0) {
|
|
int temp;
|
|
for (int x = 0; x < 0x8; x++) {
|
|
vec9 = (s16)(((s32)buffs3[x ^ 1] * (u32)env[0]) >> 0x10) ^ v2[0];
|
|
vec10 = (s16)(((s32)buffs3[x ^ 1] * (u32)env[2]) >> 0x10) ^ v2[1];
|
|
temp = bufft6[x ^ 1] + vec9;
|
|
bufft6[x ^ 1] = Saturate<s16>(temp);
|
|
temp = bufft7[x ^ 1] + vec10;
|
|
bufft7[x ^ 1] = Saturate<s16>(temp);
|
|
vec9 = (s16)(((s32)vec9 * (u32)env[4]) >> 0x10) ^ v2[2];
|
|
vec10 = (s16)(((s32)vec10 * (u32)env[4]) >> 0x10) ^ v2[3];
|
|
if (command.cmd0 & 0x10) {
|
|
temp = buffs0[x ^ 1] + vec10;
|
|
buffs0[x ^ 1] = Saturate<s16>(temp);
|
|
temp = buffs1[x ^ 1] + vec9;
|
|
buffs1[x ^ 1] = Saturate<s16>(temp);
|
|
} else {
|
|
temp = buffs0[x ^ 1] + vec9;
|
|
buffs0[x ^ 1] = Saturate<s16>(temp);
|
|
temp = buffs1[x ^ 1] + vec10;
|
|
buffs1[x ^ 1] = Saturate<s16>(temp);
|
|
}
|
|
}
|
|
|
|
if (!isMKABI)
|
|
for (int x = 0x8; x < 0x10; x++) {
|
|
vec9 = (s16)(((s32)buffs3[x ^ 1] * (u32)env[1]) >> 0x10) ^ v2[0];
|
|
vec10 = (s16)(((s32)buffs3[x ^ 1] * (u32)env[3]) >> 0x10) ^ v2[1];
|
|
temp = bufft6[x ^ 1] + vec9;
|
|
bufft6[x ^ 1] = Saturate<s16>(temp);
|
|
temp = bufft7[x ^ 1] + vec10;
|
|
bufft7[x ^ 1] = Saturate<s16>(temp);
|
|
vec9 = (s16)(((s32)vec9 * (u32)env[5]) >> 0x10) ^ v2[2];
|
|
vec10 = (s16)(((s32)vec10 * (u32)env[5]) >> 0x10) ^ v2[3];
|
|
if (command.cmd0 & 0x10) {
|
|
temp = buffs0[x ^ 1] + vec10;
|
|
buffs0[x ^ 1] = Saturate<s16>(temp);
|
|
temp = buffs1[x ^ 1] + vec9;
|
|
buffs1[x ^ 1] = Saturate<s16>(temp);
|
|
} else {
|
|
temp = buffs0[x ^ 1] + vec9;
|
|
buffs0[x ^ 1] = Saturate<s16>(temp);
|
|
temp = buffs1[x ^ 1] + vec10;
|
|
buffs1[x ^ 1] = Saturate<s16>(temp);
|
|
}
|
|
}
|
|
bufft6 += adder;
|
|
bufft7 += adder;
|
|
buffs0 += adder;
|
|
buffs1 += adder;
|
|
buffs3 += adder;
|
|
count -= adder;
|
|
env[0] = Sample_Mask(env[0] + gEnv_s5);
|
|
env[1] = Sample_Mask(env[1] + gEnv_s5);
|
|
env[2] = Sample_Mask(env[2] + gEnv_s6);
|
|
env[3] = Sample_Mask(env[3] + gEnv_s6);
|
|
env[4] = Sample_Mask(env[4] + gEnv_t3);
|
|
env[5] = Sample_Mask(env[5] + gEnv_t3);
|
|
}
|
|
}
|
|
|
|
void ENVMIXER3(AudioHLECommand command) {
|
|
u8 flags = (u8)((command.cmd0 >> 16) & 0xff);
|
|
u32 addy = (command.cmd1 & 0xFFFFFF);
|
|
|
|
s16 *inp = (s16 *)(gAudioHLEState.Buffer + 0x4F0);
|
|
s16 *out = (s16 *)(gAudioHLEState.Buffer + 0x9D0);
|
|
s16 *aux1 = (s16 *)(gAudioHLEState.Buffer + 0xB40);
|
|
s16 *aux2 = (s16 *)(gAudioHLEState.Buffer + 0xCB0);
|
|
s16 *aux3 = (s16 *)(gAudioHLEState.Buffer + 0xE20);
|
|
s32 MainL = 0, MainR = 0;
|
|
s32 AuxL = 0, AuxR = 0;
|
|
s32 i1 = 0, o1 = 0, a1 = 0, a2 = 0, a3 = 0;
|
|
|
|
s32 LAdder = 0, LAcc = 0, LVol = 0;
|
|
s32 RAdder = 0 , RAcc = 0, RVol = 0;
|
|
s16 LSig = 0, RSig = 0; // Most significant part of the Ramp Value
|
|
s16 Wet = 0, Dry = 0 ;
|
|
s16 LTrg = 0, RTrg = 0;
|
|
|
|
gAudioHLEState.VolRight = (s16)command.cmd0;
|
|
|
|
s16 *buff = (s16 *)(rdram + addy);
|
|
|
|
if (flags & A_INIT) {
|
|
LAdder = gAudioHLEState.VolRampLeft / 8;
|
|
LAcc = 0;
|
|
LVol = gAudioHLEState.VolLeft;
|
|
LSig = (s16)(gAudioHLEState.VolRampLeft >> 16);
|
|
|
|
RAdder = gAudioHLEState.VolRampRight / 8;
|
|
RAcc = 0;
|
|
RVol = gAudioHLEState.VolRight;
|
|
RSig = (s16)(gAudioHLEState.VolRampRight >> 16);
|
|
|
|
Wet = gAudioHLEState.EnvWet;
|
|
Dry = gAudioHLEState.EnvDry; // Save Wet/Dry values
|
|
LTrg = gAudioHLEState.VolTrgLeft;
|
|
RTrg = gAudioHLEState.VolTrgRight; // Save Current Left/Right Targets
|
|
} else {
|
|
Wet = *(s16 *)(buff + 0); // 0-1
|
|
Dry = *(s16 *)(buff + 2); // 2-3
|
|
LTrg = *(s16 *)(buff + 4); // 4-5
|
|
RTrg = *(s16 *)(buff + 6); // 6-7
|
|
LAdder = *(s32 *)(buff + 8); // 8-9 (buff is a 16bit pointer)
|
|
RAdder = *(s32 *)(buff + 10); // 10-11
|
|
LAcc = *(s32 *)(buff + 12); // 12-13
|
|
RAcc = *(s32 *)(buff + 14); // 14-15
|
|
LVol = *(s32 *)(buff + 16); // 16-17
|
|
RVol = *(s32 *)(buff + 18); // 18-19
|
|
LSig = *(s16 *)(buff + 20); // 20-21
|
|
RSig = *(s16 *)(buff + 22); // 22-23
|
|
// u32 test = *(s32 *)(buff + 24); // 22-23
|
|
// if (test != 0x13371337)
|
|
// __asm int 3;
|
|
}
|
|
|
|
// if(!(flags&A_AUX)) {
|
|
// AuxIncRate=0;
|
|
// aux2=aux3=zero;
|
|
// }
|
|
|
|
for (s32 y = 0; y < (0x170 / 2); y++) {
|
|
|
|
// Left
|
|
LAcc += LAdder;
|
|
LVol += (LAcc >> 16);
|
|
LAcc &= 0xFFFF;
|
|
|
|
// Right
|
|
RAcc += RAdder;
|
|
RVol += (RAcc >> 16);
|
|
RAcc &= 0xFFFF;
|
|
// ****************************************************************
|
|
// Clamp Left
|
|
if (LSig >= 0) { // VLT
|
|
if (LVol > LTrg) {
|
|
LVol = LTrg;
|
|
}
|
|
} else { // VGE
|
|
if (LVol < LTrg) {
|
|
LVol = LTrg;
|
|
}
|
|
}
|
|
|
|
// Clamp Right
|
|
if (RSig >= 0) { // VLT
|
|
if (RVol > RTrg) {
|
|
RVol = RTrg;
|
|
}
|
|
} else { // VGE
|
|
if (RVol < RTrg) {
|
|
RVol = RTrg;
|
|
}
|
|
}
|
|
// ****************************************************************
|
|
MainL = ((Dry * LVol) + 0x4000) >> 15;
|
|
MainR = ((Dry * RVol) + 0x4000) >> 15;
|
|
|
|
o1 = out[y ^ 1];
|
|
a1 = aux1[y ^ 1];
|
|
i1 = inp[y ^ 1];
|
|
|
|
o1 += ((i1 * MainL) + 0x4000) >> 15;
|
|
a1 += ((i1 * MainR) + 0x4000) >> 15;
|
|
|
|
// ****************************************************************
|
|
|
|
o1 = Saturate<s16>(o1);
|
|
a1 = Saturate<s16>(a1);
|
|
|
|
// ****************************************************************
|
|
|
|
out[y ^ 1] = o1;
|
|
aux1[y ^ 1] = a1;
|
|
|
|
// ****************************************************************
|
|
// if (!(flags&A_AUX)) {
|
|
a2 = aux2[y ^ 1];
|
|
a3 = aux3[y ^ 1];
|
|
|
|
AuxL = ((Wet * LVol) + 0x4000) >> 15;
|
|
AuxR = ((Wet * RVol) + 0x4000) >> 15;
|
|
|
|
a2 += ((i1 * AuxL) + 0x4000) >> 15;
|
|
a3 += ((i1 * AuxR) + 0x4000) >> 15;
|
|
|
|
a2 = Saturate<s16>(a2);
|
|
a3 = Saturate<s16>(a3);
|
|
|
|
aux2[y ^ 1] = a2;
|
|
aux3[y ^ 1] = a3;
|
|
}
|
|
//}
|
|
|
|
*(s16 *)(buff + 0) = Wet; // 0-1
|
|
*(s16 *)(buff + 2) = Dry; // 2-3
|
|
*(s16 *)(buff + 4) = LTrg; // 4-5
|
|
*(s16 *)(buff + 6) = RTrg; // 6-7
|
|
*(s32 *)(buff + 8) = LAdder; // 8-9 (buff is a 16bit pointer)
|
|
*(s32 *)(buff + 10) = RAdder; // 10-11
|
|
*(s32 *)(buff + 12) = LAcc; // 12-13
|
|
*(s32 *)(buff + 14) = RAcc; // 14-15
|
|
*(s32 *)(buff + 16) = LVol; // 16-17
|
|
*(s32 *)(buff + 18) = RVol; // 18-19
|
|
*(s16 *)(buff + 20) = LSig; // 20-21
|
|
*(s16 *)(buff + 22) = RSig; // 22-23
|
|
//*(u32 *)(buff + 24) = 0x13371337; // 22-23
|
|
}
|
|
|
|
void SETVOL(AudioHLECommand command) {
|
|
// Might be better to unpack these depending on the flags...
|
|
u8 flags = (u8)((command.cmd0 >> 16) & 0xff);
|
|
s16 vol = (s16)(command.cmd0 & 0xffff);
|
|
// u16 voltgt =(u16)((command.cmd1 >> 16)&0xffff);
|
|
u16 volrate = (u16)((command.cmd1 & 0xffff));
|
|
|
|
if (flags & A_AUX) {
|
|
gAudioHLEState.EnvDry = vol; // m_MainVol
|
|
gAudioHLEState.EnvWet = (s16)volrate; // m_AuxVol
|
|
} else if (flags & A_VOL) {
|
|
// Set the Source(start) Volumes
|
|
if (flags & A_LEFT) {
|
|
gAudioHLEState.VolLeft = vol;
|
|
} else {
|
|
// A_RIGHT
|
|
gAudioHLEState.VolRight = vol;
|
|
}
|
|
} else {
|
|
// Set the Ramping values Target, Ramp
|
|
if (flags & A_LEFT) {
|
|
gAudioHLEState.VolTrgLeft = (s16)(command.cmd0 & 0xffff); // m_LeftVol
|
|
gAudioHLEState.VolRampLeft = command.cmd1;
|
|
} else {
|
|
// A_RIGHT
|
|
gAudioHLEState.VolTrgRight = (s16)(command.cmd0 & 0xffff); // m_RightVol
|
|
gAudioHLEState.VolRampRight = command.cmd1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SETVOL3(AudioHLECommand command) {
|
|
u8 Flags = (u8)(command.cmd0 >> 0x10);
|
|
if (Flags & 0x4) { // 288
|
|
if (Flags & 0x2) { // 290
|
|
gAudioHLEState.VolLeft = (s16)command.cmd0; // 0x50
|
|
gAudioHLEState.EnvDry = (s16)(command.cmd1 >> 16); // 0x4E
|
|
gAudioHLEState.EnvWet = (s16)command.cmd1; // 0x4C
|
|
} else {
|
|
gAudioHLEState.VolTrgRight = (s16)command.cmd0; // 0x46
|
|
// gAudioHLEState.VolRampRight = (u16)(command.cmd1 >> 16) |
|
|
// (s32)(s16)(command.cmd1 << 0x10);
|
|
gAudioHLEState.VolRampRight = command.cmd1; // 0x48/0x4A
|
|
}
|
|
} else {
|
|
gAudioHLEState.VolTrgLeft = (s16)command.cmd0; // 0x40
|
|
gAudioHLEState.VolRampLeft = command.cmd1; // 0x42/0x44
|
|
}
|
|
}
|