#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> 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