gstreamer/gst/monkeyaudio/libmonkeyaudio/Prepare.cpp
Jeremy Simon c1a4db611b Add monkeyaudio plugin
Original commit message from CVS:
Add monkeyaudio plugin
2003-03-11 19:33:32 +00:00

517 lines
20 KiB
C++

#include "All.h"
#include "Prepare.h"
const unsigned __int32 CRC32_Table[256] = {0LU,1996959894LU,3993919788LU,2567524794LU,124634137LU,1886057615LU,3915621685LU,2657392035LU,249268274LU,2044508324LU,3772115230LU,2547177864LU,162941995LU,2125561021LU,3887607047LU,2428444049LU,498536548LU,1789927666LU,4089016648LU,2227061214LU,450548861LU,1843258603LU,4107580753LU,2211677639LU,325883990LU,1684777152LU,4251122042LU,2321926636LU,335633487LU,1661365465LU,4195302755LU,2366115317LU,997073096LU,1281953886LU,3579855332LU,2724688242LU,1006888145LU,1258607687LU,3524101629LU,2768942443LU,901097722LU,1119000684LU,3686517206LU,2898065728LU,853044451LU,1172266101LU,3705015759LU,2882616665LU,651767980LU,1373503546LU,3369554304LU,3218104598LU,565507253LU,1454621731LU,3485111705LU,3099436303LU,671266974LU,1594198024LU,3322730930LU,2970347812LU,795835527LU,1483230225LU,3244367275LU,3060149565LU,1994146192LU,31158534LU,2563907772LU,4023717930LU,1907459465LU,112637215LU,2680153253LU,3904427059LU,2013776290LU,251722036LU,2517215374LU,3775830040LU,2137656763LU,141376813LU,2439277719LU,3865271297LU,1802195444LU,476864866LU,2238001368LU,
4066508878LU,1812370925LU,453092731LU,2181625025LU,4111451223LU,1706088902LU,314042704LU,2344532202LU,4240017532LU,1658658271LU,366619977LU,2362670323LU,4224994405LU,1303535960LU,984961486LU,2747007092LU,3569037538LU,1256170817LU,1037604311LU,2765210733LU,3554079995LU,1131014506LU,879679996LU,2909243462LU,3663771856LU,1141124467LU,855842277LU,2852801631LU,3708648649LU,1342533948LU,654459306LU,3188396048LU,3373015174LU,1466479909LU,544179635LU,3110523913LU,3462522015LU,1591671054LU,702138776LU,2966460450LU,3352799412LU,1504918807LU,783551873LU,3082640443LU,3233442989LU,3988292384LU,2596254646LU,62317068LU,1957810842LU,3939845945LU,2647816111LU,81470997LU,1943803523LU,3814918930LU,2489596804LU,225274430LU,2053790376LU,3826175755LU,2466906013LU,167816743LU,2097651377LU,4027552580LU,2265490386LU,503444072LU,1762050814LU,4150417245LU,2154129355LU,426522225LU,1852507879LU,4275313526LU,2312317920LU,282753626LU,1742555852LU,4189708143LU,2394877945LU,397917763LU,1622183637LU,3604390888LU,2714866558LU,953729732LU,1340076626LU,3518719985LU,2797360999LU,1068828381LU,1219638859LU,3624741850LU,
2936675148LU,906185462LU,1090812512LU,3747672003LU,2825379669LU,829329135LU,1181335161LU,3412177804LU,3160834842LU,628085408LU,1382605366LU,3423369109LU,3138078467LU,570562233LU,1426400815LU,3317316542LU,2998733608LU,733239954LU,1555261956LU,3268935591LU,3050360625LU,752459403LU,1541320221LU,2607071920LU,3965973030LU,1969922972LU,40735498LU,2617837225LU,3943577151LU,1913087877LU,83908371LU,2512341634LU,3803740692LU,2075208622LU,213261112LU,2463272603LU,3855990285LU,2094854071LU,198958881LU,2262029012LU,4057260610LU,1759359992LU,534414190LU,2176718541LU,4139329115LU,1873836001LU,414664567LU,2282248934LU,4279200368LU,1711684554LU,285281116LU,2405801727LU,4167216745LU,1634467795LU,376229701LU,2685067896LU,3608007406LU,1308918612LU,956543938LU,2808555105LU,3495958263LU,1231636301LU,1047427035LU,2932959818LU,3654703836LU,1088359270LU,936918000LU,2847714899LU,3736837829LU,1202900863LU,817233897LU,3183342108LU,3401237130LU,1404277552LU,615818150LU,3134207493LU,3453421203LU,1423857449LU,601450431LU,3009837614LU,3294710456LU,1567103746LU,711928724LU,3020668471LU,3272380065LU,1510334235LU,755167117LU};
/*
if (nR > 32767) nR = 32767;
else if (nR < -32768) nR = -32768;
if (nL > 32767) nL = 32767;
else if (nL < -32768) nL = -32768;
*/
int CPrepare::Prepare(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
unsigned __int32 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++)
{
unsigned __int32 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++)
{
unsigned __int32 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++];
// 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++];
// 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 0;
}
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 = (__int16) nR;
CALCULATE_CRC_BYTE
CALCULATE_CRC_BYTE
*(__int16 *) pOutput = (__int16) 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;
unsigned __int32 nTemp = 0;
if (RV < 0)
nTemp = ((unsigned __int32) (RV + 0x800000)) | 0x800000;
else
nTemp = (unsigned __int32) 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 = ((unsigned __int32) (LV + 0x800000)) | 0x800000;
else
nTemp = (unsigned __int32) 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 = (__int16) 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;
unsigned __int32 nTemp = 0;
if (RV < 0)
nTemp = ((unsigned __int32) (RV + 0x800000)) | 0x800000;
else
nTemp = (unsigned __int32) 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
unsigned __int32 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];
unsigned __int32 nTemp = 0;
if (RV < 0)
nTemp = ((unsigned __int32) (RV + 0x800000)) | 0x800000;
else
nTemp = (unsigned __int32) 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 = ((unsigned __int32) (LV + 0x800000)) | 0x800000;
else
nTemp = (unsigned __int32) 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];
unsigned __int32 nTemp = 0;
if (RV < 0)
nTemp = ((unsigned __int32) (RV + 0x800000)) | 0x800000;
else
nTemp = (unsigned __int32) 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 // BACKWARDS_COMPATIBILITY