X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fmupen64plus-rsp-hle%2Fsrc%2Fucode3.c;fp=source%2Fmupen64plus-rsp-hle%2Fsrc%2Fucode3.c;h=5ef735bd81b6a472ee8b4aaf1e215d4ca44c3c57;hb=df00ea1301b9e755242364def666d5b12d470762;hp=0000000000000000000000000000000000000000;hpb=c35c7a7e99faddf004976cee07ca47055ac313b3;p=mupen64plus-pandora.git diff --git a/source/mupen64plus-rsp-hle/src/ucode3.c b/source/mupen64plus-rsp-hle/src/ucode3.c new file mode 100755 index 0000000..5ef735b --- /dev/null +++ b/source/mupen64plus-rsp-hle/src/ucode3.c @@ -0,0 +1,648 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus-rsp-hle - ucode3.c * + * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * + * Copyright (C) 2009 Richard Goedeken * + * Copyright (C) 2002 Hacktarux * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +# include +#include + +#include "m64p_plugin.h" +#include "hle.h" +#include "alist_internal.h" + +static void SETVOL3(uint32_t inst1, uint32_t inst2) +{ + uint8_t Flags = (uint8_t)(inst1 >> 0x10); + if (Flags & 0x4) { /* 288 */ + if (Flags & 0x2) { /* 290 */ + Vol_Left = (int16_t)inst1; /* 0x50 */ + Env_Dry = (int16_t)(inst2 >> 0x10); /* 0x4E */ + Env_Wet = (int16_t)inst2; /* 0x4C */ + } else { + VolTrg_Right = (int16_t)inst1; /* 0x46 */ + VolRamp_Right = (int32_t)inst2; /* 0x48/0x4A */ + } + } else { + VolTrg_Left = (int16_t)inst1; /* 0x40 */ + VolRamp_Left = (int32_t)inst2; /* 0x42/0x44 */ + } +} + +static void ENVMIXER3(uint32_t inst1, uint32_t inst2) +{ + uint8_t flags = (uint8_t)((inst1 >> 16) & 0xff); + uint32_t addy = (inst2 & 0xFFFFFF); + + short *inp = (short *)(BufferSpace + 0x4F0); + short *out = (short *)(BufferSpace + 0x9D0); + short *aux1 = (short *)(BufferSpace + 0xB40); + short *aux2 = (short *)(BufferSpace + 0xCB0); + short *aux3 = (short *)(BufferSpace + 0xE20); + int32_t MainR; + int32_t MainL; + int32_t AuxR; + int32_t AuxL; + int i1, o1, a1, a2, a3; + short zero[8]; + int y; + + int32_t LAdder, LAcc, LVol; + int32_t RAdder, RAcc, RVol; + /* Most significant part of the Ramp Value */ + int16_t RSig, LSig; + int16_t Wet, Dry; + int16_t LTrg, RTrg; + + memset(zero, 0, sizeof(zero)); + + Vol_Right = (int16_t)inst1; + + if (flags & A_INIT) { + LAdder = VolRamp_Left / 8; + LAcc = 0; + LVol = Vol_Left; + LSig = (int16_t)(VolRamp_Left >> 16); + + RAdder = VolRamp_Right / 8; + RAcc = 0; + RVol = Vol_Right; + RSig = (int16_t)(VolRamp_Right >> 16); + + /* Save Wet/Dry values */ + Wet = (int16_t)Env_Wet; + Dry = (int16_t)Env_Dry; + /* Save Current Left/Right Targets */ + LTrg = VolTrg_Left; + RTrg = VolTrg_Right; + } else { + memcpy((uint8_t *)hleMixerWorkArea, rsp.RDRAM + addy, 80); + Wet = *(int16_t *)(hleMixerWorkArea + 0); /* 0-1 */ + Dry = *(int16_t *)(hleMixerWorkArea + 2); /* 2-3 */ + LTrg = *(int16_t *)(hleMixerWorkArea + 4); /* 4-5 */ + RTrg = *(int16_t *)(hleMixerWorkArea + 6); /* 6-7 */ + LAdder = *(int32_t *)(hleMixerWorkArea + 8); /* 8-9 (hleMixerWorkArea is a 16bit pointer) */ + RAdder = *(int32_t *)(hleMixerWorkArea + 10); /* 10-11 */ + LAcc = *(int32_t *)(hleMixerWorkArea + 12); /* 12-13 */ + RAcc = *(int32_t *)(hleMixerWorkArea + 14); /* 14-15 */ + LVol = *(int32_t *)(hleMixerWorkArea + 16); /* 16-17 */ + RVol = *(int32_t *)(hleMixerWorkArea + 18); /* 18-19 */ + LSig = *(int16_t *)(hleMixerWorkArea + 20); /* 20-21 */ + RSig = *(int16_t *)(hleMixerWorkArea + 22); /* 22-23 */ + } + + for (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 ^ S]; + a1 = aux1[y ^ S]; + i1 = inp [y ^ S]; + + o1 += ((i1 * MainL) + 0x4000) >> 15; + a1 += ((i1 * MainR) + 0x4000) >> 15; + +/****************************************************************/ + o1 = clamp_s16(o1); + a1 = clamp_s16(a1); + +/****************************************************************/ + + out[y ^ S] = o1; + aux1[y ^ S] = a1; + +/****************************************************************/ + a2 = aux2[y ^ S]; + a3 = aux3[y ^ S]; + + AuxL = ((Wet * LVol) + 0x4000) >> 15; + AuxR = ((Wet * RVol) + 0x4000) >> 15; + + a2 += ((i1 * AuxL) + 0x4000) >> 15; + a3 += ((i1 * AuxR) + 0x4000) >> 15; + + a2 = clamp_s16(a2); + a3 = clamp_s16(a3); + + aux2[y ^ S] = a2; + aux3[y ^ S] = a3; + } + + *(int16_t *)(hleMixerWorkArea + 0) = Wet; /* 0-1 */ + *(int16_t *)(hleMixerWorkArea + 2) = Dry; /* 2-3 */ + *(int16_t *)(hleMixerWorkArea + 4) = LTrg; /* 4-5 */ + *(int16_t *)(hleMixerWorkArea + 6) = RTrg; /* 6-7 */ + *(int32_t *)(hleMixerWorkArea + 8) = LAdder; /* 8-9 (hleMixerWorkArea is a 16bit pointer) */ + *(int32_t *)(hleMixerWorkArea + 10) = RAdder; /* 10-11 */ + *(int32_t *)(hleMixerWorkArea + 12) = LAcc; /* 12-13 */ + *(int32_t *)(hleMixerWorkArea + 14) = RAcc; /* 14-15 */ + *(int32_t *)(hleMixerWorkArea + 16) = LVol; /* 16-17 */ + *(int32_t *)(hleMixerWorkArea + 18) = RVol; /* 18-19 */ + *(int16_t *)(hleMixerWorkArea + 20) = LSig; /* 20-21 */ + *(int16_t *)(hleMixerWorkArea + 22) = RSig; /* 22-23 */ + memcpy(rsp.RDRAM + addy, (uint8_t *)hleMixerWorkArea, 80); +} + +static void CLEARBUFF3(uint32_t inst1, uint32_t inst2) +{ + uint16_t addr = (uint16_t)(inst1 & 0xffff); + uint16_t count = (uint16_t)(inst2 & 0xffff); + memset(BufferSpace + addr + 0x4f0, 0, count); +} + +/* TODO Needs accuracy verification... */ +static void MIXER3(uint32_t inst1, uint32_t inst2) +{ + uint16_t dmemin = (uint16_t)(inst2 >> 0x10) + 0x4f0; + uint16_t dmemout = (uint16_t)(inst2 & 0xFFFF) + 0x4f0; + int32_t gain = (int16_t)(inst1 & 0xFFFF); + int32_t temp; + int x; + + for (x = 0; x < 0x170; x += 2) { + /* TODO I think I can do this a lot easier */ + temp = (*(int16_t *)(BufferSpace + dmemin + x) * gain) >> 15; + temp += *(int16_t *)(BufferSpace + dmemout + x); + + temp = clamp_s16((int32_t)temp); + + *(uint16_t *)(BufferSpace + dmemout + x) = (uint16_t)(temp & 0xFFFF); + } +} + +static void LOADBUFF3(uint32_t inst1, uint32_t inst2) +{ + uint32_t v0 = (inst2 & 0xfffffc); + uint32_t cnt = (((inst1 >> 0xC) + 3) & 0xFFC); + uint32_t src = (inst1 & 0xffc) + 0x4f0; + memcpy(BufferSpace + src, rsp.RDRAM + v0, cnt); +} + +static void SAVEBUFF3(uint32_t inst1, uint32_t inst2) +{ + uint32_t v0 = (inst2 & 0xfffffc); + uint32_t cnt = (((inst1 >> 0xC) + 3) & 0xFFC); + uint32_t src = (inst1 & 0xffc) + 0x4f0; + memcpy(rsp.RDRAM + v0, BufferSpace + src, cnt); +} + +/* Loads an ADPCM table + * NOTE Works 100% Now 03-13-01 + */ +static void LOADADPCM3(uint32_t inst1, uint32_t inst2) +{ + uint32_t v0 = (inst2 & 0xffffff); + uint32_t x; + + uint16_t *table = (uint16_t *)(rsp.RDRAM + v0); + for (x = 0; x < ((inst1 & 0xffff) >> 0x4); x++) { + adpcmtable[(0x0 + (x << 3))^S] = table[0]; + adpcmtable[(0x1 + (x << 3))^S] = table[1]; + + adpcmtable[(0x2 + (x << 3))^S] = table[2]; + adpcmtable[(0x3 + (x << 3))^S] = table[3]; + + adpcmtable[(0x4 + (x << 3))^S] = table[4]; + adpcmtable[(0x5 + (x << 3))^S] = table[5]; + + adpcmtable[(0x6 + (x << 3))^S] = table[6]; + adpcmtable[(0x7 + (x << 3))^S] = table[7]; + table += 8; + } +} + +/* TODO Needs accuracy verification... */ +static void DMEMMOVE3(uint32_t inst1, uint32_t inst2) +{ + uint32_t cnt; + uint32_t v0 = (inst1 & 0xFFFF) + 0x4f0; + uint32_t v1 = (inst2 >> 0x10) + 0x4f0; + uint32_t count = ((inst2 + 3) & 0xfffc); + + for (cnt = 0; cnt < count; cnt++) + *(uint8_t *)(BufferSpace + ((cnt + v1)^S8)) = *(uint8_t *)(BufferSpace + ((cnt + v0)^S8)); +} + +static void SETLOOP3(uint32_t inst1, uint32_t inst2) +{ + loopval = (inst2 & 0xffffff); +} + +/* TODO Verified to be 100% Accurate... */ +static void ADPCM3(uint32_t inst1, uint32_t inst2) +{ + unsigned char Flags = (uint8_t)(inst2 >> 0x1c) & 0xff; + unsigned int Address = (inst1 & 0xffffff); + unsigned short inPtr = (inst2 >> 12) & 0xf; + short *out = (short *)(BufferSpace + (inst2 & 0xfff) + 0x4f0); + short count = (short)((inst2 >> 16) & 0xfff); + unsigned char icode; + unsigned char code; + int vscale; + unsigned short index; + unsigned short j; + int a[8]; + short *book1, *book2; + int l1; + int l2; + int inp1[8]; + int inp2[8]; + + memset(out, 0, 32); + + if (!(Flags & 0x1)) { + if (Flags & 0x2) + memcpy(out, &rsp.RDRAM[loopval], 32); + else + memcpy(out, &rsp.RDRAM[Address], 32); + } + + l1 = out[14 ^ S]; + l2 = out[15 ^ S]; + 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 = BufferSpace[(0x4f0 + inPtr)^S8]; + index = code & 0xf; + /* index into the adpcm code table */ + index <<= 4; + book1 = (short *)&adpcmtable[index]; + book2 = book1 + 8; + /* upper nibble is scale */ + code >>= 4; + /* 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 + */ + vscale = (0x8000 >> ((12 - code) - 1)); + + /* coded adpcm data lies next */ + inPtr++; + j = 0; + /* loop of 8, for 8 coded nibbles from 4 bytes + * which yields 8 short pcm values + */ + while (j < 8) { + icode = BufferSpace[(0x4f0 + inPtr)^S8]; + inPtr++; + + /* this will in effect be signed */ + inp1[j] = (int16_t)((icode & 0xf0) << 8); + if (code < 12) + inp1[j] = ((int)((int)inp1[j] * (int)vscale) >> 16); + j++; + + inp1[j] = (int16_t)((icode & 0xf) << 12); + if (code < 12) + inp1[j] = ((int)((int)inp1[j] * (int)vscale) >> 16); + j++; + } + j = 0; + while (j < 8) { + icode = BufferSpace[(0x4f0 + inPtr)^S8]; + inPtr++; + + /* this will in effect be signed */ + inp2[j] = (short)((icode & 0xf0) << 8); + if (code < 12) + inp2[j] = ((int)((int)inp2[j] * (int)vscale) >> 16); + j++; + + inp2[j] = (short)((icode & 0xf) << 12); + if (code < 12) + inp2[j] = ((int)((int)inp2[j] * (int)vscale) >> 16); + j++; + } + + a[0] = (int)book1[0] * (int)l1; + a[0] += (int)book2[0] * (int)l2; + a[0] += (int)inp1[0] * (int)2048; + + a[1] = (int)book1[1] * (int)l1; + a[1] += (int)book2[1] * (int)l2; + a[1] += (int)book2[0] * inp1[0]; + a[1] += (int)inp1[1] * (int)2048; + + a[2] = (int)book1[2] * (int)l1; + a[2] += (int)book2[2] * (int)l2; + a[2] += (int)book2[1] * inp1[0]; + a[2] += (int)book2[0] * inp1[1]; + a[2] += (int)inp1[2] * (int)2048; + + a[3] = (int)book1[3] * (int)l1; + a[3] += (int)book2[3] * (int)l2; + a[3] += (int)book2[2] * inp1[0]; + a[3] += (int)book2[1] * inp1[1]; + a[3] += (int)book2[0] * inp1[2]; + a[3] += (int)inp1[3] * (int)2048; + + a[4] = (int)book1[4] * (int)l1; + a[4] += (int)book2[4] * (int)l2; + a[4] += (int)book2[3] * inp1[0]; + a[4] += (int)book2[2] * inp1[1]; + a[4] += (int)book2[1] * inp1[2]; + a[4] += (int)book2[0] * inp1[3]; + a[4] += (int)inp1[4] * (int)2048; + + a[5] = (int)book1[5] * (int)l1; + a[5] += (int)book2[5] * (int)l2; + a[5] += (int)book2[4] * inp1[0]; + a[5] += (int)book2[3] * inp1[1]; + a[5] += (int)book2[2] * inp1[2]; + a[5] += (int)book2[1] * inp1[3]; + a[5] += (int)book2[0] * inp1[4]; + a[5] += (int)inp1[5] * (int)2048; + + a[6] = (int)book1[6] * (int)l1; + a[6] += (int)book2[6] * (int)l2; + a[6] += (int)book2[5] * inp1[0]; + a[6] += (int)book2[4] * inp1[1]; + a[6] += (int)book2[3] * inp1[2]; + a[6] += (int)book2[2] * inp1[3]; + a[6] += (int)book2[1] * inp1[4]; + a[6] += (int)book2[0] * inp1[5]; + a[6] += (int)inp1[6] * (int)2048; + + a[7] = (int)book1[7] * (int)l1; + a[7] += (int)book2[7] * (int)l2; + a[7] += (int)book2[6] * inp1[0]; + a[7] += (int)book2[5] * inp1[1]; + a[7] += (int)book2[4] * inp1[2]; + a[7] += (int)book2[3] * inp1[3]; + a[7] += (int)book2[2] * inp1[4]; + a[7] += (int)book2[1] * inp1[5]; + a[7] += (int)book2[0] * inp1[6]; + a[7] += (int)inp1[7] * (int)2048; + + for (j = 0; j < 8; j++) { + a[j ^ S] >>= 11; + a[j ^ S] = clamp_s16(a[j ^ S]); + *(out++) = a[j ^ S]; + } + l1 = a[6]; + l2 = a[7]; + + a[0] = (int)book1[0] * (int)l1; + a[0] += (int)book2[0] * (int)l2; + a[0] += (int)inp2[0] * (int)2048; + + a[1] = (int)book1[1] * (int)l1; + a[1] += (int)book2[1] * (int)l2; + a[1] += (int)book2[0] * inp2[0]; + a[1] += (int)inp2[1] * (int)2048; + + a[2] = (int)book1[2] * (int)l1; + a[2] += (int)book2[2] * (int)l2; + a[2] += (int)book2[1] * inp2[0]; + a[2] += (int)book2[0] * inp2[1]; + a[2] += (int)inp2[2] * (int)2048; + + a[3] = (int)book1[3] * (int)l1; + a[3] += (int)book2[3] * (int)l2; + a[3] += (int)book2[2] * inp2[0]; + a[3] += (int)book2[1] * inp2[1]; + a[3] += (int)book2[0] * inp2[2]; + a[3] += (int)inp2[3] * (int)2048; + + a[4] = (int)book1[4] * (int)l1; + a[4] += (int)book2[4] * (int)l2; + a[4] += (int)book2[3] * inp2[0]; + a[4] += (int)book2[2] * inp2[1]; + a[4] += (int)book2[1] * inp2[2]; + a[4] += (int)book2[0] * inp2[3]; + a[4] += (int)inp2[4] * (int)2048; + + a[5] = (int)book1[5] * (int)l1; + a[5] += (int)book2[5] * (int)l2; + a[5] += (int)book2[4] * inp2[0]; + a[5] += (int)book2[3] * inp2[1]; + a[5] += (int)book2[2] * inp2[2]; + a[5] += (int)book2[1] * inp2[3]; + a[5] += (int)book2[0] * inp2[4]; + a[5] += (int)inp2[5] * (int)2048; + + a[6] = (int)book1[6] * (int)l1; + a[6] += (int)book2[6] * (int)l2; + a[6] += (int)book2[5] * inp2[0]; + a[6] += (int)book2[4] * inp2[1]; + a[6] += (int)book2[3] * inp2[2]; + a[6] += (int)book2[2] * inp2[3]; + a[6] += (int)book2[1] * inp2[4]; + a[6] += (int)book2[0] * inp2[5]; + a[6] += (int)inp2[6] * (int)2048; + + a[7] = (int)book1[7] * (int)l1; + a[7] += (int)book2[7] * (int)l2; + a[7] += (int)book2[6] * inp2[0]; + a[7] += (int)book2[5] * inp2[1]; + a[7] += (int)book2[4] * inp2[2]; + a[7] += (int)book2[3] * inp2[3]; + a[7] += (int)book2[2] * inp2[4]; + a[7] += (int)book2[1] * inp2[5]; + a[7] += (int)book2[0] * inp2[6]; + a[7] += (int)inp2[7] * (int)2048; + + for (j = 0; j < 8; j++) { + a[j ^ S] >>= 11; + a[j ^ S] = clamp_s16(a[j ^ S]); + *(out++) = a[j ^ S]; + } + l1 = a[6]; + l2 = a[7]; + + count -= 32; + } + out -= 16; + memcpy(&rsp.RDRAM[Address], out, 32); +} + +static void RESAMPLE3(uint32_t inst1, uint32_t inst2) +{ + unsigned char Flags = (uint8_t)((inst2 >> 0x1e)); + unsigned int Pitch = ((inst2 >> 0xe) & 0xffff) << 1; + uint32_t addy = (inst1 & 0xffffff); + unsigned int Accum = 0; + unsigned int location; + int16_t *lut; + short *dst; + int16_t *src; + uint32_t srcPtr = ((((inst2 >> 2) & 0xfff) + 0x4f0) / 2); + uint32_t dstPtr; + int32_t temp; + int32_t accum; + int x, i; + + dst = (short *)(BufferSpace); + src = (int16_t *)(BufferSpace); + + srcPtr -= 4; + + if (inst2 & 0x3) + dstPtr = 0x660 / 2; + else + dstPtr = 0x4f0 / 2; + + if ((Flags & 0x1) == 0) { + for (x = 0; x < 4; x++) + src[(srcPtr + x)^S] = ((uint16_t *)rsp.RDRAM)[((addy / 2) + x)^S]; + Accum = *(uint16_t *)(rsp.RDRAM + addy + 10); + } else { + for (x = 0; x < 4; x++) + src[(srcPtr + x)^S] = 0; + } + + for (i = 0; i < 0x170 / 2; i++) { + location = (((Accum * 0x40) >> 0x10) * 8); + lut = (int16_t *)(((uint8_t *)ResampleLUT) + location); + + temp = ((int32_t) * (int16_t *)(src + ((srcPtr + 0)^S)) * ((int32_t)((int16_t)lut[0]))); + accum = (int32_t)(temp >> 15); + + temp = ((int32_t) * (int16_t *)(src + ((srcPtr + 1)^S)) * ((int32_t)((int16_t)lut[1]))); + accum += (int32_t)(temp >> 15); + + temp = ((int32_t) * (int16_t *)(src + ((srcPtr + 2)^S)) * ((int32_t)((int16_t)lut[2]))); + accum += (int32_t)(temp >> 15); + + temp = ((int32_t) * (int16_t *)(src + ((srcPtr + 3)^S)) * ((int32_t)((int16_t)lut[3]))); + accum += (int32_t)(temp >> 15); + + accum = clamp_s16(accum); + + dst[dstPtr ^ S] = (accum); + dstPtr++; + Accum += Pitch; + srcPtr += (Accum >> 16); + Accum &= 0xffff; + } + for (x = 0; x < 4; x++) + ((uint16_t *)rsp.RDRAM)[((addy / 2) + x)^S] = src[(srcPtr + x)^S]; + *(uint16_t *)(rsp.RDRAM + addy + 10) = Accum; +} + +/* TODO Needs accuracy verification... */ +static void INTERLEAVE3(uint32_t inst1, uint32_t inst2) +{ + uint16_t *outbuff = (uint16_t *)(BufferSpace + 0x4f0); + uint16_t *inSrcR; + uint16_t *inSrcL; + uint16_t Left, Right, Left2, Right2; + int x; + + inSrcR = (uint16_t *)(BufferSpace + 0xb40); + inSrcL = (uint16_t *)(BufferSpace + 0x9d0); + + for (x = 0; x < (0x170 / 4); x++) { + Left = *(inSrcL++); + Right = *(inSrcR++); + Left2 = *(inSrcL++); + Right2 = *(inSrcR++); + +#ifdef M64P_BIG_ENDIAN + *(outbuff++) = Right; + *(outbuff++) = Left; + *(outbuff++) = Right2; + *(outbuff++) = Left2; +#else + *(outbuff++) = Right2; + *(outbuff++) = Left2; + *(outbuff++) = Right; + *(outbuff++) = Left; +#endif + } +} + +static void WHATISTHIS(uint32_t inst1, uint32_t inst2) +{ +} + +static uint32_t setaddr; +static void MP3ADDY(uint32_t inst1, uint32_t inst2) +{ + setaddr = (inst2 & 0xffffff); +} + +/* +FFT = Fast Fourier Transform +DCT = Discrete Cosine Transform +MPEG-1 Layer 3 retains Layer 2's 1152-sample window, as well as the FFT polyphase filter for +backward compatibility, but adds a modified DCT filter. DCT's advantages over DFTs (discrete +Fourier transforms) include half as many multiply-accumulate operations and half the +generated coefficients because the sinusoidal portion of the calculation is absent, and DCT +generally involves simpler math. The finite lengths of a conventional DCTs' bandpass impulse +responses, however, may result in block-boundary effects. MDCTs overlap the analysis blocks +and lowpass-filter the decoded audio to remove aliases, eliminating these effects. MDCTs also +have a higher transform coding gain than the standard DCT, and their basic functions +correspond to better bandpass response. + +MPEG-1 Layer 3's DCT sub-bands are unequally sized, and correspond to the human auditory +system's critical bands. In Layer 3 decoders must support both constant- and variable-bit-rate +bit streams. (However, many Layer 1 and 2 decoders also handle variable bit rates). Finally, +Layer 3 encoders Huffman-code the quantized coefficients before archiving or transmission for +additional lossless compression. Bit streams range from 32 to 320 kbps, and 128-kbps rates +achieve near-CD quality, an important specification to enable dual-channel ISDN +(integrated-services-digital-network) to be the future high-bandwidth pipe to the home. + +*/ +static void DISABLE(uint32_t inst1, uint32_t inst2) +{ +} + + +const acmd_callback_t ABI3[0x10] = { + DISABLE , ADPCM3 , CLEARBUFF3, ENVMIXER3 , LOADBUFF3, RESAMPLE3 , SAVEBUFF3, MP3, + MP3ADDY, SETVOL3, DMEMMOVE3 , LOADADPCM3 , MIXER3 , INTERLEAVE3, WHATISTHIS , SETLOOP3 +};