cog/Libraries/MAC/Files/Source/MACLib/Prepare.cpp

538 lines
21 KiB
C++
Executable File

#include "All.h"
#include "Prepare.h"
const uint32 CRC32_TABLE[256] = {0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,
4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,
2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918000,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117};
#define READ_BUFFER(var,shift) \
var |= (unsigned char)*pRawData << (shift); \
CRC = ((unsigned int)CRC >> 8) ^ CRC32_TABLE [(CRC & 0xFF) ^ (unsigned char)*pRawData++]
#define READ_BUFFER0(var,shift) \
var = (unsigned char)*pRawData << (shift); \
CRC = ((unsigned int)CRC >> 8) ^ CRC32_TABLE [(CRC & 0xFF) ^ (unsigned char)*pRawData++]
#define READ_BUFFERS(var,shift) \
var |= (char)(*pRawData) << (shift); \
CRC = ((unsigned int)CRC >> 8) ^ CRC32_TABLE [(CRC & 0xFF) ^ (unsigned char)*pRawData++]
#define READ_BUFFERS0(var,shift) \
var = (char)(*pRawData) << (shift); \
CRC = ((unsigned int)CRC >> 8) ^ CRC32_TABLE [(CRC & 0xFF) ^ (unsigned char)*pRawData++]
int CPrepare::Prepare(const unsigned char * pRawData, int nBytes, const WAVEFORMATEX * pWaveFormatEx, int * pOutputX, int *pOutputY, unsigned int *pCRC, int *pSpecialCodes, int *pPeakLevel)
{
// error check the parameters
if (pRawData == NULL || pWaveFormatEx == NULL)
return ERROR_BAD_PARAMETER;
// initialize the pointers that got passed in
*pCRC = 0xFFFFFFFF;
*pSpecialCodes = 0;
// variables
uint32 CRC = 0xFFFFFFFF;
const int nTotalBlocks = nBytes / pWaveFormatEx->nBlockAlign;
int R,L;
// the prepare code
if (pWaveFormatEx->wBitsPerSample == 8)
{
if (pWaveFormatEx->nChannels == 2)
{
for (int nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++)
{
R = (int) (*((unsigned char *) pRawData) - 128);
L = (int) (*((unsigned char *) (pRawData + 1)) - 128);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
// check the peak
if (labs(L) > *pPeakLevel)
*pPeakLevel = labs(L);
if (labs(R) > *pPeakLevel)
*pPeakLevel = labs(R);
// convert to x,y
pOutputY[nBlockIndex] = L - R;
pOutputX[nBlockIndex] = R + (pOutputY[nBlockIndex] / 2);
}
}
else if (pWaveFormatEx->nChannels == 1)
{
for (int nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++)
{
R = (int) (*((unsigned char *) pRawData) - 128);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
// check the peak
if (labs(R) > *pPeakLevel)
*pPeakLevel = labs(R);
// convert to x,y
pOutputX[nBlockIndex] = R;
}
}
}
else if (pWaveFormatEx->wBitsPerSample == 24)
{
if (pWaveFormatEx->nChannels == 2)
{
for (int nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++)
{
uint32 nTemp = 0;
nTemp |= (*pRawData << 0);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
nTemp |= (*pRawData << 8);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
nTemp |= (*pRawData << 16);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
if (nTemp & 0x800000)
R = (int) (nTemp & 0x7FFFFF) - 0x800000;
else
R = (int) (nTemp & 0x7FFFFF);
nTemp = 0;
nTemp |= (*pRawData << 0);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
nTemp |= (*pRawData << 8);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
nTemp |= (*pRawData << 16);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
if (nTemp & 0x800000)
L = (int) (nTemp & 0x7FFFFF) - 0x800000;
else
L = (int) (nTemp & 0x7FFFFF);
// check the peak
if (labs(L) > *pPeakLevel)
*pPeakLevel = labs(L);
if (labs(R) > *pPeakLevel)
*pPeakLevel = labs(R);
// convert to x,y
pOutputY[nBlockIndex] = L - R;
pOutputX[nBlockIndex] = R + (pOutputY[nBlockIndex] / 2);
}
}
else if (pWaveFormatEx->nChannels == 1)
{
for (int nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++)
{
uint32 nTemp = 0;
nTemp |= (*pRawData << 0);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
nTemp |= (*pRawData << 8);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
nTemp |= (*pRawData << 16);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
if (nTemp & 0x800000)
R = (int) (nTemp & 0x7FFFFF) - 0x800000;
else
R = (int) (nTemp & 0x7FFFFF);
// check the peak
if (labs(R) > *pPeakLevel)
*pPeakLevel = labs(R);
// convert to x,y
pOutputX[nBlockIndex] = R;
}
}
}
else
{
if (pWaveFormatEx->nChannels == 2)
{
int LPeak = 0;
int RPeak = 0;
int nBlockIndex = 0;
for (nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++)
{
/*
R = (int) *((int16 *) pRawData);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
L = (int) *((int16 *) pRawData);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
*/
READ_BUFFER0( R, 0 );
READ_BUFFERS( R, 8 );
READ_BUFFER0( L, 0 );
READ_BUFFERS( L, 8 );
// check the peak
if (labs(L) > LPeak)
LPeak = labs(L);
if (labs(R) > RPeak)
RPeak = labs(R);
// convert to x,y
pOutputY[nBlockIndex] = L - R;
pOutputX[nBlockIndex] = R + (pOutputY[nBlockIndex] / 2);
}
if (LPeak == 0) { *pSpecialCodes |= SPECIAL_FRAME_LEFT_SILENCE; }
if (RPeak == 0) { *pSpecialCodes |= SPECIAL_FRAME_RIGHT_SILENCE; }
if (max(LPeak, RPeak) > *pPeakLevel)
{
*pPeakLevel = max(LPeak, RPeak);
}
// check for pseudo-stereo files
nBlockIndex = 0;
while (pOutputY[nBlockIndex++] == 0)
{
if (nBlockIndex == (nBytes / 4))
{
*pSpecialCodes |= SPECIAL_FRAME_PSEUDO_STEREO;
break;
}
}
}
else if (pWaveFormatEx->nChannels == 1)
{
int nPeak = 0;
for (int nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++)
{
/*
R = (int) *((int16 *) pRawData);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++];
*/
READ_BUFFER0 ( R, 0 );
READ_BUFFERS ( R, 8 );
// check the peak
if (labs(R) > nPeak)
nPeak = labs(R);
//convert to x,y
pOutputX[nBlockIndex] = R;
}
if (nPeak > *pPeakLevel)
*pPeakLevel = nPeak;
if (nPeak == 0) { *pSpecialCodes |= SPECIAL_FRAME_MONO_SILENCE; }
}
}
CRC = CRC ^ 0xFFFFFFFF;
// add the special code
CRC >>= 1;
if (*pSpecialCodes != 0)
{
CRC |= (1 << 31);
}
*pCRC = CRC;
return ERROR_SUCCESS;
}
void CPrepare::Unprepare(int X, int Y, const WAVEFORMATEX * pWaveFormatEx, unsigned char * pOutput, unsigned int * pCRC)
{
#define CALCULATE_CRC_BYTE *pCRC = (*pCRC >> 8) ^ CRC32_TABLE[(*pCRC & 0xFF) ^ *pOutput++];
// decompress and convert from (x,y) -> (l,r)
// sort of long and ugly.... sorry
if (pWaveFormatEx->nChannels == 2)
{
if (pWaveFormatEx->wBitsPerSample == 16)
{
// get the right and left values
int nR = X - (Y / 2);
int nL = nR + Y;
// error check (for overflows)
if ((nR < -32768) || (nR > 32767) || (nL < -32768) || (nL > 32767))
{
throw(-1);
}
*(int16 *) pOutput = swap_endian16(nR);
CALCULATE_CRC_BYTE
CALCULATE_CRC_BYTE
*(int16 *) pOutput = swap_endian16(nL);
CALCULATE_CRC_BYTE
CALCULATE_CRC_BYTE
}
else if (pWaveFormatEx->wBitsPerSample == 8)
{
unsigned char R = (X - (Y / 2) + 128);
*pOutput = R;
CALCULATE_CRC_BYTE
*pOutput = (unsigned char) (R + Y);
CALCULATE_CRC_BYTE
}
else if (pWaveFormatEx->wBitsPerSample == 24)
{
int32 RV, LV;
RV = X - (Y / 2);
LV = RV + Y;
uint32 nTemp = 0;
if (RV < 0)
nTemp = ((uint32) (RV + 0x800000)) | 0x800000;
else
nTemp = (uint32) RV;
*pOutput = (unsigned char) ((nTemp >> 0) & 0xFF);
CALCULATE_CRC_BYTE
*pOutput = (unsigned char) ((nTemp >> 8) & 0xFF);
CALCULATE_CRC_BYTE
*pOutput = (unsigned char) ((nTemp >> 16) & 0xFF);
CALCULATE_CRC_BYTE
nTemp = 0;
if (LV < 0)
nTemp = ((uint32) (LV + 0x800000)) | 0x800000;
else
nTemp = (uint32) LV;
*pOutput = (unsigned char) ((nTemp >> 0) & 0xFF);
CALCULATE_CRC_BYTE
*pOutput = (unsigned char) ((nTemp >> 8) & 0xFF);
CALCULATE_CRC_BYTE
*pOutput = (unsigned char) ((nTemp >> 16) & 0xFF);
CALCULATE_CRC_BYTE
}
}
else if (pWaveFormatEx->nChannels == 1)
{
if (pWaveFormatEx->wBitsPerSample == 16)
{
int16 R = X;
*(int16 *) pOutput = swap_endian16(R);;
CALCULATE_CRC_BYTE
CALCULATE_CRC_BYTE
}
else if (pWaveFormatEx->wBitsPerSample == 8)
{
unsigned char R = X + 128;
*pOutput = R;
CALCULATE_CRC_BYTE
}
else if (pWaveFormatEx->wBitsPerSample == 24)
{
int32 RV = X;
uint32 nTemp = 0;
if (RV < 0)
nTemp = ((uint32) (RV + 0x800000)) | 0x800000;
else
nTemp = (uint32) RV;
*pOutput = (unsigned char) ((nTemp >> 0) & 0xFF);
CALCULATE_CRC_BYTE
*pOutput = (unsigned char) ((nTemp >> 8) & 0xFF);
CALCULATE_CRC_BYTE
*pOutput = (unsigned char) ((nTemp >> 16) & 0xFF);
CALCULATE_CRC_BYTE
}
}
}
#ifdef BACKWARDS_COMPATIBILITY
int CPrepare::UnprepareOld(int *pInputX, int *pInputY, int nBlocks, const WAVEFORMATEX *pWaveFormatEx, unsigned char *pRawData, unsigned int *pCRC, int *pSpecialCodes, int nFileVersion)
{
// the CRC that will be figured during decompression
uint32 CRC = 0xFFFFFFFF;
// decompress and convert from (x,y) -> (l,r)
// sort of int and ugly.... sorry
if (pWaveFormatEx->nChannels == 2)
{
// convert the x,y data to raw data
if (pWaveFormatEx->wBitsPerSample == 16)
{
int16 R;
unsigned char *Buffer = &pRawData[0];
int *pX = pInputX;
int *pY = pInputY;
for (; pX < &pInputX[nBlocks]; pX++, pY++)
{
R = *pX - (*pY / 2);
*(int16 *) Buffer = (int16) R;
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
*(int16 *) Buffer = (int16) R + *pY;
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
}
}
else if (pWaveFormatEx->wBitsPerSample == 8)
{
unsigned char *R = (unsigned char *) &pRawData[0];
unsigned char *L = (unsigned char *) &pRawData[1];
if (nFileVersion > 3830)
{
for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++, L+=2, R+=2)
{
*R = (unsigned char) (pInputX[SampleIndex] - (pInputY[SampleIndex] / 2) + 128);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *R];
*L = (unsigned char) (*R + pInputY[SampleIndex]);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *L];
}
}
else
{
for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++, L+=2, R+=2)
{
*R = (unsigned char) (pInputX[SampleIndex] - (pInputY[SampleIndex] / 2));
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *R];
*L = (unsigned char) (*R + pInputY[SampleIndex]);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *L];
}
}
}
else if (pWaveFormatEx->wBitsPerSample == 24)
{
unsigned char *Buffer = (unsigned char *) &pRawData[0];
int32 RV, LV;
for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++)
{
RV = pInputX[SampleIndex] - (pInputY[SampleIndex] / 2);
LV = RV + pInputY[SampleIndex];
uint32 nTemp = 0;
if (RV < 0)
nTemp = ((uint32) (RV + 0x800000)) | 0x800000;
else
nTemp = (uint32) RV;
*Buffer = (unsigned char) ((nTemp >> 0) & 0xFF);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
*Buffer = (unsigned char) ((nTemp >> 8) & 0xFF);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
*Buffer = (unsigned char) ((nTemp >> 16) & 0xFF);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
nTemp = 0;
if (LV < 0)
nTemp = ((uint32) (LV + 0x800000)) | 0x800000;
else
nTemp = (uint32) LV;
*Buffer = (unsigned char) ((nTemp >> 0) & 0xFF);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
*Buffer = (unsigned char) ((nTemp >> 8) & 0xFF);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
*Buffer = (unsigned char) ((nTemp >> 16) & 0xFF);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
}
}
}
else if (pWaveFormatEx->nChannels == 1)
{
// convert to raw data
if (pWaveFormatEx->wBitsPerSample == 8)
{
unsigned char *R = (unsigned char *) &pRawData[0];
if (nFileVersion > 3830)
{
for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++, R++)
{
*R = pInputX[SampleIndex] + 128;
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *R];
}
}
else
{
for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++, R++)
{
*R = (unsigned char) (pInputX[SampleIndex]);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *R];
}
}
}
else if (pWaveFormatEx->wBitsPerSample == 24)
{
unsigned char *Buffer = (unsigned char *) &pRawData[0];
int32 RV;
for (int SampleIndex = 0; SampleIndex<nBlocks; SampleIndex++)
{
RV = pInputX[SampleIndex];
uint32 nTemp = 0;
if (RV < 0)
nTemp = ((uint32) (RV + 0x800000)) | 0x800000;
else
nTemp = (uint32) RV;
*Buffer = (unsigned char) ((nTemp >> 0) & 0xFF);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
*Buffer = (unsigned char) ((nTemp >> 8) & 0xFF);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
*Buffer = (unsigned char) ((nTemp >> 16) & 0xFF);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
}
}
else
{
unsigned char *Buffer = &pRawData[0];
for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++)
{
*(int16 *) Buffer = (int16) (pInputX[SampleIndex]);
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++];
}
}
}
CRC = CRC ^ 0xFFFFFFFF;
*pCRC = CRC;
return 0;
}
#endif // #ifdef BACKWARDS_COMPATIBILITY