mirror of
https://github.com/DaedalusX64/daedalus.git
synced 2025-04-02 10:21:48 -04:00
484 lines
16 KiB
C++
484 lines
16 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;
|
|
|
|
void ADPCM(AudioHLECommand command) {
|
|
u8 flags = command.Abi1ADPCM.Flags;
|
|
// u16 gain( command.Abi1ADPCM.Gain ); // Not used?
|
|
u32 address = command.Abi1ADPCM.Address + gAudioHLEState.Segments[(command.cmd1>>24)&0xf];
|
|
|
|
gAudioHLEState.ADPCMDecode(flags, address);
|
|
}
|
|
|
|
inline int Scale16(s16 in, int vscale) { return ((int)in * vscale) >> 16; }
|
|
|
|
void Decode4_Scale(std::array<int, 8> &inp1, u32 icode_a, u32 icode_b, int vscale) {
|
|
inp1[0] = Scale16((s16)((icode_a & 0xC0) << 8), vscale);
|
|
inp1[1] = Scale16((s16)((icode_a & 0x30) << 10), vscale);
|
|
inp1[2] = Scale16((s16)((icode_a & 0x0C) << 12), vscale);
|
|
inp1[3] = Scale16((s16)((icode_a & 0x03) << 14), vscale);
|
|
inp1[4] = Scale16((s16)((icode_b & 0xC0) << 8), vscale);
|
|
inp1[5] = Scale16((s16)((icode_b & 0x30) << 10), vscale);
|
|
inp1[6] = Scale16((s16)((icode_b & 0x0C) << 12), vscale);
|
|
inp1[7] = Scale16((s16)((icode_b & 0x03) << 14), vscale);
|
|
}
|
|
|
|
// void Decode4(int (&inp1)[8], u32 icode_a, u32 icode_b) {
|
|
void Decode4(std::array<int, 8> &inp1, u32 icode_a, u32 icode_b) {
|
|
inp1[0] = (s16)((icode_a & 0xC0) << 8);
|
|
inp1[1] = (s16)((icode_a & 0x30) << 10);
|
|
inp1[2] = (s16)((icode_a & 0x0C) << 12);
|
|
inp1[3] = (s16)((icode_a & 0x03) << 14);
|
|
inp1[4] = (s16)((icode_b & 0xC0) << 8);
|
|
inp1[5] = (s16)((icode_b & 0x30) << 10);
|
|
inp1[6] = (s16)((icode_b & 0x0C) << 12);
|
|
inp1[7] = (s16)((icode_b & 0x03) << 14);
|
|
}
|
|
|
|
// void Decode8_Scale(int (&inp1)[8], u32 icode_a, u32 icode_b, u32 icode_c,
|
|
void Decode8_Scale(std::array<int, 8> &inp1, u32 icode_a, u32 icode_b, u32 icode_c,
|
|
u32 icode_d, int vscale) {
|
|
inp1[0] = Scale16((s16)((icode_a & 0xF0) << 8), vscale);
|
|
inp1[1] = Scale16((s16)((icode_a & 0x0F) << 12), vscale);
|
|
inp1[2] = Scale16((s16)((icode_b & 0xF0) << 8), vscale);
|
|
inp1[3] = Scale16((s16)((icode_b & 0x0F) << 12), vscale);
|
|
inp1[4] = Scale16((s16)((icode_c & 0xF0) << 8), vscale);
|
|
inp1[5] = Scale16((s16)((icode_c & 0x0F) << 12), vscale);
|
|
inp1[6] = Scale16((s16)((icode_d & 0xF0) << 8), vscale);
|
|
inp1[7] = Scale16((s16)((icode_d & 0x0F) << 12), vscale);
|
|
}
|
|
|
|
void Decode8(std::array<int, 8> &inp1, u32 icode_a, u32 icode_b, u32 icode_c,
|
|
u32 icode_d) {
|
|
inp1[0] = (s16)((icode_a & 0xF0) << 8);
|
|
inp1[1] = (s16)((icode_a & 0x0F) << 12);
|
|
inp1[2] = (s16)((icode_b & 0xF0) << 8);
|
|
inp1[3] = (s16)((icode_b & 0x0F) << 12);
|
|
inp1[4] = (s16)((icode_c & 0xF0) << 8);
|
|
inp1[5] = (s16)((icode_c & 0x0F) << 12);
|
|
inp1[6] = (s16)((icode_d & 0xF0) << 8);
|
|
inp1[7] = (s16)((icode_d & 0x0F) << 12);
|
|
}
|
|
|
|
void ADPCM2_Decode4(std::array<int, 8> &inp1, std::array<int, 8> &inp2, u32 inPtr, u8 code) {
|
|
u32 icode_a =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 0) ^ 3];
|
|
u32 icode_b =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 1) ^ 3];
|
|
u32 icode_c =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 2) ^ 3];
|
|
u32 icode_d =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 3) ^ 3];
|
|
|
|
if (code < 0xE) {
|
|
int vscale(0x8000 >> ((0xE - code) - 1));
|
|
Decode4_Scale(inp1, icode_a, icode_b, vscale);
|
|
Decode4_Scale(inp2, icode_c, icode_d, vscale);
|
|
} else {
|
|
Decode4(inp1, icode_a, icode_b);
|
|
Decode4(inp2, icode_c, icode_d);
|
|
}
|
|
}
|
|
|
|
void ADPCM2_Decode8(std::array<int, 8> &inp1, std::array<int, 8> &inp2, u32 inPtr, u8 code) {
|
|
u32 icode_a =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 0) ^ 3];
|
|
u32 icode_b =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 1) ^ 3];
|
|
u32 icode_c =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 2) ^ 3];
|
|
u32 icode_d =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 3) ^ 3];
|
|
u32 icode_e =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 4) ^ 3];
|
|
u32 icode_f =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 5) ^ 3];
|
|
u32 icode_g =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 6) ^ 3];
|
|
u32 icode_h =
|
|
gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr + 7) ^ 3];
|
|
|
|
if (code < 0xC) {
|
|
int vscale(0x8000 >> ((0xC - code) - 1));
|
|
Decode8_Scale(inp1, icode_a, icode_b, icode_c, icode_d, vscale);
|
|
Decode8_Scale(inp2, icode_e, icode_f, icode_g, icode_h, vscale);
|
|
} else {
|
|
Decode8(inp1, icode_a, icode_b, icode_c, icode_d);
|
|
Decode8(inp2, icode_e, icode_f, icode_g, icode_h);
|
|
}
|
|
}
|
|
|
|
// void ADPCM2_Loop(s32 (&a)[8], int (&i1)[8], const s16 *b1, const s16 *b2,
|
|
// s16 *out) {
|
|
// int l1(a[6]);
|
|
// int l2(a[7]);
|
|
// void ADPCM2_Loop(s32 (&a)[8], int (&i1)[8], const s16 *b1, const s16 *b2, s16 *out) {
|
|
void ADPCM2_Loop(std::array<s32, 8> (&a), std::array<int, 8> &i1, const s16 *b1, const s16 *b2, s16 *out) {
|
|
|
|
int l1(a[6]);
|
|
int l2(a[7]);
|
|
|
|
|
|
const int scl = 2048;
|
|
|
|
a[0] = ((int)b1[0] * l1) + ((int)b2[0] * l2) + ((int)i1[0] * scl);
|
|
a[1] = ((int)b1[1] * l1) + ((int)b2[1] * l2) + ((int)b2[0] * i1[0]) +
|
|
((int)i1[1] * scl);
|
|
a[2] = ((int)b1[2] * l1) + ((int)b2[2] * l2) + ((int)b2[1] * i1[0]) +
|
|
((int)b2[0] * i1[1]) + ((int)i1[2] * scl);
|
|
a[3] = ((int)b1[3] * l1) + ((int)b2[3] * l2) + ((int)b2[2] * i1[0]) +
|
|
((int)b2[1] * i1[1]) + ((int)b2[0] * i1[2]) + ((int)i1[3] * scl);
|
|
a[4] = ((int)b1[4] * l1) + ((int)b2[4] * l2) + ((int)b2[3] * i1[0]) +
|
|
((int)b2[2] * i1[1]) + ((int)b2[1] * i1[2]) + ((int)b2[0] * i1[3]) +
|
|
((int)i1[4] * scl);
|
|
a[5] = ((int)b1[5] * l1) + ((int)b2[5] * l2) + ((int)b2[4] * i1[0]) +
|
|
((int)b2[3] * i1[1]) + ((int)b2[2] * i1[2]) + ((int)b2[1] * i1[3]) +
|
|
((int)b2[0] * i1[4]) + ((int)i1[5] * scl);
|
|
a[6] = ((int)b1[6] * l1) + ((int)b2[6] * l2) + ((int)b2[5] * i1[0]) +
|
|
((int)b2[4] * i1[1]) + ((int)b2[3] * i1[2]) + ((int)b2[2] * i1[3]) +
|
|
((int)b2[1] * i1[4]) + ((int)b2[0] * i1[5]) + ((int)i1[6] * scl);
|
|
a[7] = ((int)b1[7] * l1) + ((int)b2[7] * l2) + ((int)b2[6] * i1[0]) +
|
|
((int)b2[5] * i1[1]) + ((int)b2[4] * i1[2]) + ((int)b2[3] * i1[3]) +
|
|
((int)b2[2] * i1[4]) + ((int)b2[1] * i1[5]) + ((int)b2[0] * i1[6]) +
|
|
((int)i1[7] * scl);
|
|
|
|
for (u32 j = 0; j < 8; j++) {
|
|
s16 r = Saturate<s16>(a[j ^ 1] >> 11);
|
|
a[j ^ 1] = r;
|
|
out[j] = r; // XXXX endian issues
|
|
}
|
|
}
|
|
void ADPCM2(AudioHLECommand command) {
|
|
|
|
// Verified to be 100% Accurate...
|
|
u8 Flags = (u8)((command.cmd0 >> 16) & 0xff);
|
|
// u16 Gain=(u16)(command.cmd0&0xffff); // XXXX Unused
|
|
u32 Address = command.cmd1 &
|
|
0xffffff+ gAudioHLEState.Segments[(command.cmd1>>24)&0xf];
|
|
|
|
bool init = (Flags & 0x1) != 0;
|
|
bool loop = (Flags & 0x2) != 0;
|
|
bool decode4 = (Flags & 0x4) != 0; // 4 bytes -> 16 output samples
|
|
|
|
s16 *out((s16 *)(gAudioHLEState.Buffer + gAudioHLEState.OutBuffer));
|
|
if (init) {
|
|
memset(out, 0, 32);
|
|
} else {
|
|
u32 src_addr = loop ? gAudioHLEState.LoopVal : Address;
|
|
memmove(out, &rdram[src_addr], 32); // XXXX Endian issues?
|
|
}
|
|
|
|
u16 inPtr = 0;
|
|
|
|
// s32 a[8] = {
|
|
std::array<s32,8> a = {
|
|
0, 0, 0, 0,
|
|
0, 0, out[15], out[14]}; // XXXX Endian issues - should be 14/15^TWIDDLE?
|
|
|
|
out += 16;
|
|
short count = gAudioHLEState.Count;
|
|
while (count > 0) {
|
|
u8 idx_code = gAudioHLEState.Buffer[(gAudioHLEState.InBuffer + inPtr) ^ 3];
|
|
inPtr++;
|
|
|
|
u16 index = (idx_code & 0xf) << 4;
|
|
u8 code = idx_code >>= 4;
|
|
|
|
s16 *book1 = (s16 *)&gAudioHLEState.ADPCMTable[index];
|
|
s16 *book2 = book1 + 8;
|
|
|
|
// Decode inputs
|
|
std::array<int, 8> inp1;
|
|
std::array<int, 8> inp2;
|
|
// int inp1[8];
|
|
// int inp2[8];
|
|
|
|
if (decode4) {
|
|
ADPCM2_Decode4(inp1, inp2, inPtr, code);
|
|
inPtr += 4;
|
|
} else {
|
|
ADPCM2_Decode8(inp1, inp2, inPtr, code);
|
|
inPtr += 8;
|
|
}
|
|
|
|
// Generate samples
|
|
ADPCM2_Loop(a, inp1, book1, book2, out);
|
|
ADPCM2_Loop(a, inp2, book1, book2, out + 8);
|
|
|
|
out += 16;
|
|
count -= 32;
|
|
}
|
|
out -= 16;
|
|
memmove(&rdram[Address], out, 32);
|
|
}
|
|
|
|
void ADPCM3(AudioHLECommand command) {
|
|
u8 Flags = (u8)(command.cmd1 >> 0x1c) & 0xff;
|
|
// u16 Gain=(u16)(command.cmd0&0xffff);
|
|
u32 Address =
|
|
(command.cmd0 &
|
|
0xffffff)+ gAudioHLEState.Segments[(command.cmd1>>24)&0xf];
|
|
u32 inPtr = (command.cmd1 >> 12) & 0xf;
|
|
// s16 *out=(s16 *)(testbuff+(gAudioHLEState.OutBuffer>>2));
|
|
s16 *out = (s16 *)(gAudioHLEState.Buffer + (command.cmd1 & 0xfff) + 0x4f0);
|
|
// u8 *in=(u8 *)(gAudioHLEState.Buffer+((command.cmd1>>12)&0xf)+0x4f0);
|
|
s16 count = (s16)((command.cmd1 >> 16) & 0xfff);
|
|
u8 icode;
|
|
u8 code;
|
|
s32 vscale;
|
|
u16 index;
|
|
u16 j;
|
|
std::array<s32, 8> a;
|
|
// s32 a[8];
|
|
s16 *book1, *book2;
|
|
|
|
memset(out, 0, 32);
|
|
|
|
if (!(Flags & 0x1)) {
|
|
memmove(out, &rdram[(Flags & 0x2) ? gAudioHLEState.LoopVal : Address], 32);
|
|
}
|
|
|
|
// s32 l1 =std::array<s32, 15> out;
|
|
// s32 l2 = std::array<s32, 14> out;
|
|
s32 l1 = out[15];
|
|
s32 l2 = out[14];
|
|
std::array<s32, 8> inp1;
|
|
std::array<s32, 8> inp2;
|
|
// s32 inp1[8];
|
|
// s32 inp2[8];
|
|
out += 16;
|
|
while (count > 0) {
|
|
// the first interation through, these values are
|
|
// either 0 in the case of A_INIT, from a special
|
|
// area of memory in the case of A_LOOP or just
|
|
// the values we calculated the last time
|
|
|
|
code = gAudioHLEState.Buffer[(0x4f0 + inPtr) ^ 3];
|
|
index = code & 0xf;
|
|
index <<= 4; // index into the adpcm code table
|
|
book1 = (s16 *)&gAudioHLEState.ADPCMTable[index];
|
|
book2 = book1 + 8;
|
|
code >>= 4; // upper nibble is scale
|
|
vscale = (0x8000 >> ((12 - code) -
|
|
1)); // very strange. 0x8000 would be .5 in 16:16
|
|
// format so this appears to be a fractional scale
|
|
// based on the 12 based inverse of the scale
|
|
// value. note that this could be negative, in
|
|
// which case we do not use the calculated vscale
|
|
// value... see the if(code>12) check below
|
|
|
|
inPtr++; // coded adpcm data lies next
|
|
j = 0;
|
|
while (j < 8) // loop of 8, for 8 coded nibbles from 4 bytes
|
|
// which yields 8 s16 pcm values
|
|
{
|
|
icode = gAudioHLEState.Buffer[(0x4f0 + inPtr) ^ 3];
|
|
inPtr++;
|
|
|
|
inp1[j] = (s16)((icode & 0xf0) << 8); // this will in effect be signed
|
|
|
|
// Conker and Banjo set this!
|
|
if (code < 12)
|
|
inp1[j] = ((s32)((s32)inp1[j] * (s32)vscale) >> 16);
|
|
|
|
j++;
|
|
|
|
inp1[j] = (s16)((icode & 0xf) << 12);
|
|
|
|
inp1[j] = ((s32)((s32)inp1[j] * (s32)vscale) >> 16);
|
|
j++;
|
|
}
|
|
|
|
j = 0;
|
|
while (j < 8) {
|
|
icode = gAudioHLEState.Buffer[(0x4f0 + inPtr) ^ 3];
|
|
inPtr++;
|
|
|
|
inp2[j] = (s16)((icode & 0xf0) << 8); // this will in effect be signed
|
|
|
|
if (code < 12)
|
|
inp2[j] = ((s32)((s32)inp2[j] * (s32)vscale) >> 16);
|
|
|
|
j++;
|
|
|
|
inp2[j] = (s16)((icode & 0xf) << 12);
|
|
|
|
inp2[j] = ((s32)((s32)inp2[j] * (s32)vscale) >> 16);
|
|
j++;
|
|
}
|
|
|
|
a[0] = (s32)book1[0] * (s32)l1;
|
|
a[0] += (s32)book2[0] * (s32)l2;
|
|
a[0] += (s32)inp1[0] * (s32)2048;
|
|
|
|
a[1] = (s32)book1[1] * (s32)l1;
|
|
a[1] += (s32)book2[1] * (s32)l2;
|
|
a[1] += (s32)book2[0] * inp1[0];
|
|
a[1] += (s32)inp1[1] * (s32)2048;
|
|
|
|
a[2] = (s32)book1[2] * (s32)l1;
|
|
a[2] += (s32)book2[2] * (s32)l2;
|
|
a[2] += (s32)book2[1] * inp1[0];
|
|
a[2] += (s32)book2[0] * inp1[1];
|
|
a[2] += (s32)inp1[2] * (s32)2048;
|
|
|
|
a[3] = (s32)book1[3] * (s32)l1;
|
|
a[3] += (s32)book2[3] * (s32)l2;
|
|
a[3] += (s32)book2[2] * inp1[0];
|
|
a[3] += (s32)book2[1] * inp1[1];
|
|
a[3] += (s32)book2[0] * inp1[2];
|
|
a[3] += (s32)inp1[3] * (s32)2048;
|
|
|
|
a[4] = (s32)book1[4] * (s32)l1;
|
|
a[4] += (s32)book2[4] * (s32)l2;
|
|
a[4] += (s32)book2[3] * inp1[0];
|
|
a[4] += (s32)book2[2] * inp1[1];
|
|
a[4] += (s32)book2[1] * inp1[2];
|
|
a[4] += (s32)book2[0] * inp1[3];
|
|
a[4] += (s32)inp1[4] * (s32)2048;
|
|
|
|
a[5] = (s32)book1[5] * (s32)l1;
|
|
a[5] += (s32)book2[5] * (s32)l2;
|
|
a[5] += (s32)book2[4] * inp1[0];
|
|
a[5] += (s32)book2[3] * inp1[1];
|
|
a[5] += (s32)book2[2] * inp1[2];
|
|
a[5] += (s32)book2[1] * inp1[3];
|
|
a[5] += (s32)book2[0] * inp1[4];
|
|
a[5] += (s32)inp1[5] * (s32)2048;
|
|
|
|
a[6] = (s32)book1[6] * (s32)l1;
|
|
a[6] += (s32)book2[6] * (s32)l2;
|
|
a[6] += (s32)book2[5] * inp1[0];
|
|
a[6] += (s32)book2[4] * inp1[1];
|
|
a[6] += (s32)book2[3] * inp1[2];
|
|
a[6] += (s32)book2[2] * inp1[3];
|
|
a[6] += (s32)book2[1] * inp1[4];
|
|
a[6] += (s32)book2[0] * inp1[5];
|
|
a[6] += (s32)inp1[6] * (s32)2048;
|
|
|
|
a[7] = (s32)book1[7] * (s32)l1;
|
|
a[7] += (s32)book2[7] * (s32)l2;
|
|
a[7] += (s32)book2[6] * inp1[0];
|
|
a[7] += (s32)book2[5] * inp1[1];
|
|
a[7] += (s32)book2[4] * inp1[2];
|
|
a[7] += (s32)book2[3] * inp1[3];
|
|
a[7] += (s32)book2[2] * inp1[4];
|
|
a[7] += (s32)book2[1] * inp1[5];
|
|
a[7] += (s32)book2[0] * inp1[6];
|
|
a[7] += (s32)inp1[7] * (s32)2048;
|
|
|
|
*(out++) = Saturate<s16>(a[1] >> 11);
|
|
*(out++) = Saturate<s16>(a[0] >> 11);
|
|
*(out++) = Saturate<s16>(a[3] >> 11);
|
|
*(out++) = Saturate<s16>(a[2] >> 11);
|
|
*(out++) = Saturate<s16>(a[5] >> 11);
|
|
*(out++) = Saturate<s16>(a[4] >> 11);
|
|
*(out++) = l2 = Saturate<s16>(a[7] >> 11);
|
|
*(out++) = l1 = Saturate<s16>(a[6] >> 11);
|
|
|
|
a[0] = (s32)book1[0] * (s32)l1;
|
|
a[0] += (s32)book2[0] * (s32)l2;
|
|
a[0] += (s32)inp2[0] * (s32)2048;
|
|
|
|
a[1] = (s32)book1[1] * (s32)l1;
|
|
a[1] += (s32)book2[1] * (s32)l2;
|
|
a[1] += (s32)book2[0] * inp2[0];
|
|
a[1] += (s32)inp2[1] * (s32)2048;
|
|
|
|
a[2] = (s32)book1[2] * (s32)l1;
|
|
a[2] += (s32)book2[2] * (s32)l2;
|
|
a[2] += (s32)book2[1] * inp2[0];
|
|
a[2] += (s32)book2[0] * inp2[1];
|
|
a[2] += (s32)inp2[2] * (s32)2048;
|
|
|
|
a[3] = (s32)book1[3] * (s32)l1;
|
|
a[3] += (s32)book2[3] * (s32)l2;
|
|
a[3] += (s32)book2[2] * inp2[0];
|
|
a[3] += (s32)book2[1] * inp2[1];
|
|
a[3] += (s32)book2[0] * inp2[2];
|
|
a[3] += (s32)inp2[3] * (s32)2048;
|
|
|
|
a[4] = (s32)book1[4] * (s32)l1;
|
|
a[4] += (s32)book2[4] * (s32)l2;
|
|
a[4] += (s32)book2[3] * inp2[0];
|
|
a[4] += (s32)book2[2] * inp2[1];
|
|
a[4] += (s32)book2[1] * inp2[2];
|
|
a[4] += (s32)book2[0] * inp2[3];
|
|
a[4] += (s32)inp2[4] * (s32)2048;
|
|
|
|
a[5] = (s32)book1[5] * (s32)l1;
|
|
a[5] += (s32)book2[5] * (s32)l2;
|
|
a[5] += (s32)book2[4] * inp2[0];
|
|
a[5] += (s32)book2[3] * inp2[1];
|
|
a[5] += (s32)book2[2] * inp2[2];
|
|
a[5] += (s32)book2[1] * inp2[3];
|
|
a[5] += (s32)book2[0] * inp2[4];
|
|
a[5] += (s32)inp2[5] * (s32)2048;
|
|
|
|
a[6] = (s32)book1[6] * (s32)l1;
|
|
a[6] += (s32)book2[6] * (s32)l2;
|
|
a[6] += (s32)book2[5] * inp2[0];
|
|
a[6] += (s32)book2[4] * inp2[1];
|
|
a[6] += (s32)book2[3] * inp2[2];
|
|
a[6] += (s32)book2[2] * inp2[3];
|
|
a[6] += (s32)book2[1] * inp2[4];
|
|
a[6] += (s32)book2[0] * inp2[5];
|
|
a[6] += (s32)inp2[6] * (s32)2048;
|
|
|
|
a[7] = (s32)book1[7] * (s32)l1;
|
|
a[7] += (s32)book2[7] * (s32)l2;
|
|
a[7] += (s32)book2[6] * inp2[0];
|
|
a[7] += (s32)book2[5] * inp2[1];
|
|
a[7] += (s32)book2[4] * inp2[2];
|
|
a[7] += (s32)book2[3] * inp2[3];
|
|
a[7] += (s32)book2[2] * inp2[4];
|
|
a[7] += (s32)book2[1] * inp2[5];
|
|
a[7] += (s32)book2[0] * inp2[6];
|
|
a[7] += (s32)inp2[7] * (s32)2048;
|
|
|
|
*(out++) = Saturate<s16>(a[1] >> 11);
|
|
*(out++) = Saturate<s16>(a[0] >> 11);
|
|
*(out++) = Saturate<s16>(a[3] >> 11);
|
|
*(out++) = Saturate<s16>(a[2] >> 11);
|
|
*(out++) = Saturate<s16>(a[5] >> 11);
|
|
*(out++) = Saturate<s16>(a[4] >> 11);
|
|
*(out++) = l2 = Saturate<s16>(a[7] >> 11);
|
|
*(out++) = l1 = Saturate<s16>(a[6] >> 11);
|
|
|
|
count -= 32;
|
|
}
|
|
out -= 16;
|
|
memmove(&rdram[Address], out, 32);
|
|
}
|
|
|
|
void LOADADPCM(AudioHLECommand command) {
|
|
u32 address = command.Abi1LoadADPCM .Address+ gAudioHLEState.Segments[(command.cmd1>>24)&0xf];
|
|
u16 count = command.Abi1LoadADPCM.Count;
|
|
|
|
gAudioHLEState.LoadADPCM(address, count);
|
|
}
|
|
|
|
void LOADADPCM2(AudioHLECommand command) {
|
|
// Loads an ADPCM table - Works 100% Now 03-13-01
|
|
u32 address = command.Abi2LoadADPCM.Address+ gAudioHLEState.Segments[(command.cmd1>>24)&0xf];
|
|
u16 count = command.Abi2LoadADPCM.Count;
|
|
|
|
gAudioHLEState.LoadADPCM(address, count);
|
|
}
|
|
|
|
void LOADADPCM3(AudioHLECommand command) {
|
|
u32 address = command.Abi3LoadADPCM.Address+ gAudioHLEState.Segments[(command.cmd1>>24)&0xf];
|
|
u16 count = command.Abi3LoadADPCM.Count;
|
|
|
|
gAudioHLEState.LoadADPCM(address, count);
|
|
}
|