cog/Libraries/MAC/Files/Source/MACLib/Old/AntiPredictorNormal.cpp

263 lines
7.2 KiB
C++
Executable File

#include "All.h"
#ifdef BACKWARDS_COMPATIBILITY
#include "Anti-Predictor.h"
#ifdef ENABLE_COMPRESSION_MODE_NORMAL
void CAntiPredictorNormal0000To3320::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements)
{
// variable declares
int *ip, *op, *op1, *op2;
int p, pw;
int m;
// short frame handling
if (NumberOfElements < 32)
{
memcpy(pOutputArray, pInputArray, NumberOfElements * 4);
return;
}
////////////////////////////////////////
// order 3
////////////////////////////////////////
memcpy(pOutputArray, pInputArray, 32);
// initialize values
m = 300;
op = &pOutputArray[8];
op1 = &pOutputArray[7];
op2 = &pOutputArray[6];
// make the first prediction
p = (pOutputArray[7] * 3) - (pOutputArray[6] * 3) + pOutputArray[5];
pw = (p * m) >> 12;
// loop through the array
for (ip = &pInputArray[8]; ip < &pInputArray[NumberOfElements]; ip++, op++, op1++, op2++) {
// figure the output value
*op = *ip + pw;
// adjust m
if (*ip > 0)
m += (p > 0) ? 4 : -4;
else if (*ip < 0)
m += (p > 0) ? -4 : 4;
// make the next prediction
p = (*op * 3) - (*op1 * 3) + *op2;
pw = (p * m) >> 12;
}
///////////////////////////////////////
// order 2
///////////////////////////////////////
memcpy(pInputArray, pOutputArray, 32);
m = 3000;
op1 = &pInputArray[7];
p = (*op1 * 2) - pInputArray[6];
pw = (p * m) >> 12;
for (op = &pInputArray[8], ip = &pOutputArray[8]; ip < &pOutputArray[NumberOfElements]; ip++, op++, op1++)
{
*op = *ip + pw;
// adjust m
if (*ip > 0)
m += (p > 0) ? 12 : -12;
else if (*ip < 0)
m += (p > 0) ? -12 : 12;
p = (*op * 2) - *op1;
pw = (p * m) >> 12;
}
///////////////////////////////////////
// order 1
///////////////////////////////////////
pOutputArray[0] = pInputArray[0];
pOutputArray[1] = pInputArray[1] + pOutputArray[0];
pOutputArray[2] = pInputArray[2] + pOutputArray[1];
pOutputArray[3] = pInputArray[3] + pOutputArray[2];
pOutputArray[4] = pInputArray[4] + pOutputArray[3];
pOutputArray[5] = pInputArray[5] + pOutputArray[4];
pOutputArray[6] = pInputArray[6] + pOutputArray[5];
pOutputArray[7] = pInputArray[7] + pOutputArray[6];
m = 3900;
p = pOutputArray[7];
pw = (p * m) >> 12;
for (op = &pOutputArray[8], ip = &pInputArray[8]; ip < &pInputArray[NumberOfElements]; ip++, op++) {
*op = *ip + pw;
// adjust m
if (*ip > 0)
m += (p > 0) ? 1 : -1;
else if (*ip < 0)
m += (p > 0) ? -1 : 1;
p = *op;
pw = (p * m) >> 12;
}
}
void CAntiPredictorNormal3320To3800::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements)
{
// variable declares
int q;
// short frame handling
if (NumberOfElements < 8)
{
memcpy(pOutputArray, pInputArray, NumberOfElements * 4);
return;
}
// make the first five samples identical in both arrays
memcpy(pOutputArray, pInputArray, 20);
// initialize values
int m1 = 0;
int m2 = 64;
int m3 = 28;
int OP0;
int OP1 = pOutputArray[4];
int p3 = (3 * (pOutputArray[4] - pOutputArray[3])) + pOutputArray[2];
int p2 = pInputArray[4] + ((pInputArray[2] - pInputArray[3]) << 3) - pInputArray[1] + pInputArray[0];
int p1 = pOutputArray[4];
for (q = 5; q < NumberOfElements; q++)
{
OP0 = pInputArray[q] + ((p1 * m1) >> 8);
(pInputArray[q] ^ p1) > 0 ? m1++ : m1--;
p1 = OP0;
pInputArray[q] = OP0 + ((p2 * m2) >> 11);
(OP0 ^ p2) > 0 ? m2++ : m2--;
p2 = pInputArray[q] + ((pInputArray[q - 2] - pInputArray[q - 1]) << 3) - pInputArray[q - 3] + pInputArray[q - 4];
pOutputArray[q] = pInputArray[q] + ((p3 * m3) >> 9);
(pInputArray[q] ^ p3) > 0 ? m3++ : m3--;
p3 = (3 * (pOutputArray[q] - pOutputArray[q - 1])) + pOutputArray[q - 2];
}
int m4 = 370;
int m5 = 3900;
pOutputArray[1] = pInputArray[1] + pOutputArray[0];
pOutputArray[2] = pInputArray[2] + pOutputArray[1];
pOutputArray[3] = pInputArray[3] + pOutputArray[2];
pOutputArray[4] = pInputArray[4] + pOutputArray[3];
int p4 = (2 * pInputArray[4]) - pInputArray[3];
int p5 = pOutputArray[4];
int IP0, IP1;
IP1 = pInputArray[4];
for (q = 5; q < NumberOfElements; q++)
{
IP0 = pOutputArray[q] + ((p4 * m4) >> 9);
(pOutputArray[q] ^ p4) > 0 ? m4++ : m4--;
p4 = (2 * IP0) - IP1;
pOutputArray[q] = IP0 + ((p5 * m5) >> 12);
(IP0 ^ p5) > 0 ? m5++ : m5--;
p5 = pOutputArray[q];
IP1 = IP0;
}
}
void CAntiPredictorNormal3800ToCurrent::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements)
{
// the frame to start prediction on
#define FIRST_ELEMENT 4
// short frame handling
if (NumberOfElements < 8)
{
memcpy(pOutputArray, pInputArray, NumberOfElements * 4);
return;
}
// make the first five samples identical in both arrays
memcpy(pOutputArray, pInputArray, FIRST_ELEMENT * 4);
// variable declares and initializations
int m2 = 64, m3 = 115, m4 = 64, m5 = 740, m6 = 0;
int p4 = pInputArray[FIRST_ELEMENT - 1];
int p3 = (pInputArray[FIRST_ELEMENT - 1] - pInputArray[FIRST_ELEMENT - 2]) << 1;
int p2 = pInputArray[FIRST_ELEMENT - 1] + ((pInputArray[FIRST_ELEMENT - 3] - pInputArray[FIRST_ELEMENT - 2]) << 3);// - pInputArray[3] + pInputArray[2];
int *op = &pOutputArray[FIRST_ELEMENT];
int *ip = &pInputArray[FIRST_ELEMENT];
int IPP2 = ip[-2];
int p7 = 2 * ip[-1] - ip[-2];
int opp = op[-1];
// undo the initial prediction stuff
for (int q = 1; q < FIRST_ELEMENT; q++) {
pOutputArray[q] += pOutputArray[q - 1];
}
// pump the primary loop
for (; op < &pOutputArray[NumberOfElements]; op++, ip++) {
register int o = *op, i = *ip;
/////////////////////////////////////////////
o = i + (((p2 * m2) + (p3 * m3) + (p4 * m4)) >> 11);
if (i > 0)
{
m2 -= ((p2 >> 30) & 2) - 1;
m3 -= ((p3 >> 28) & 8) - 4;
m4 -= ((p4 >> 28) & 8) - 4;
}
else if (i < 0)
{
m2 += ((p2 >> 30) & 2) - 1;
m3 += ((p3 >> 28) & 8) - 4;
m4 += ((p4 >> 28) & 8) - 4;
}
p2 = o + ((IPP2 - p4) << 3);
p3 = (o - p4) << 1;
IPP2 = p4;
p4 = o;
/////////////////////////////////////////////
o += (((p7 * m5) - (opp * m6)) >> 10);
if (p4 > 0)
{
m5 -= ((p7 >> 29) & 4) - 2;
m6 += ((opp >> 30) & 2) - 1;
}
else if (p4 < 0)
{
m5 += ((p7 >> 29) & 4) - 2;
m6 -= ((opp >> 30) & 2) - 1;
}
p7 = 2 * o - opp;
opp = o;
/////////////////////////////////////////////
*op = o + ((op[-1] * 31) >> 5);
}
}
#endif // #ifdef ENABLE_COMPRESSION_MODE_NORMAL
#endif // #ifdef BACKWARDS_COMPATIBILITY