1#include "All.h" 2#include "APECompressCore.h" 3 4#include "BitArray.h" 5#include "Prepare.h" 6#include "NewPredictor.h" 7 8CAPECompressCore::CAPECompressCore(CIO * pIO, const WAVEFORMATEX * pwfeInput, int nMaxFrameBlocks, int nCompressionLevel) 9{ 10 m_spBitArray.Assign(new CBitArray(pIO)); 11 m_spDataX.Assign(new int [nMaxFrameBlocks], TRUE); 12 m_spDataY.Assign(new int [nMaxFrameBlocks], TRUE); 13 m_spTempData.Assign(new int [nMaxFrameBlocks], TRUE); 14 m_spPrepare.Assign(new CPrepare); 15 m_spPredictorX.Assign(new CPredictorCompressNormal(nCompressionLevel)); 16 m_spPredictorY.Assign(new CPredictorCompressNormal(nCompressionLevel)); 17 18 memcpy(&m_wfeInput, pwfeInput, sizeof(WAVEFORMATEX)); 19 m_nPeakLevel = 0; 20} 21 22CAPECompressCore::~CAPECompressCore() 23{ 24} 25 26int CAPECompressCore::EncodeFrame(const void * pInputData, int nInputBytes) 27{ 28 // variables 29 const int nInputBlocks = nInputBytes / m_wfeInput.nBlockAlign; 30 int nSpecialCodes = 0; 31 32 // always start a new frame on a byte boundary 33 m_spBitArray->AdvanceToByteBoundary(); 34 35 // do the preparation stage 36 RETURN_ON_ERROR(Prepare(pInputData, nInputBytes, &nSpecialCodes)) 37 38 m_spPredictorX->Flush(); 39 m_spPredictorY->Flush(); 40 41 m_spBitArray->FlushState(m_BitArrayStateX); 42 m_spBitArray->FlushState(m_BitArrayStateY); 43 44 m_spBitArray->FlushBitArray(); 45 46 if (m_wfeInput.nChannels == 2) 47 { 48 BOOL bEncodeX = TRUE; 49 BOOL bEncodeY = TRUE; 50 51 if ((nSpecialCodes & SPECIAL_FRAME_LEFT_SILENCE) && 52 (nSpecialCodes & SPECIAL_FRAME_RIGHT_SILENCE)) 53 { 54 bEncodeX = FALSE; 55 bEncodeY = FALSE; 56 } 57 58 if (nSpecialCodes & SPECIAL_FRAME_PSEUDO_STEREO) 59 { 60 bEncodeY = FALSE; 61 } 62 63 if (bEncodeX && bEncodeY) 64 { 65 int nLastX = 0; 66 for (int z = 0; z < nInputBlocks; z++) 67 { 68 m_spBitArray->EncodeValue(m_spPredictorY->CompressValue(m_spDataY[z], nLastX), m_BitArrayStateY); 69 m_spBitArray->EncodeValue(m_spPredictorX->CompressValue(m_spDataX[z], m_spDataY[z]), m_BitArrayStateX); 70 71 nLastX = m_spDataX[z]; 72 } 73 } 74 else if (bEncodeX) 75 { 76 for (int z = 0; z < nInputBlocks; z++) 77 { 78 RETURN_ON_ERROR(m_spBitArray->EncodeValue(m_spPredictorX->CompressValue(m_spDataX[z]), m_BitArrayStateX)) 79 } 80 } 81 else if (bEncodeY) 82 { 83 for (int z = 0; z < nInputBlocks; z++) 84 { 85 RETURN_ON_ERROR(m_spBitArray->EncodeValue(m_spPredictorY->CompressValue(m_spDataY[z]), m_BitArrayStateY)) 86 } 87 } 88 } 89 else if (m_wfeInput.nChannels == 1) 90 { 91 if (!(nSpecialCodes & SPECIAL_FRAME_MONO_SILENCE)) 92 { 93 for (int z = 0; z < nInputBlocks; z++) 94 { 95 RETURN_ON_ERROR(m_spBitArray->EncodeValue(m_spPredictorX->CompressValue(m_spDataX[z]), m_BitArrayStateX)) 96 } 97 } 98 } 99 100 m_spBitArray->Finalize(); 101 102 // return success 103 return 0; 104} 105 106int CAPECompressCore::Prepare(const void * pInputData, int nInputBytes, int * pSpecialCodes) 107{ 108 // variable declares 109 *pSpecialCodes = 0; 110 unsigned int nCRC = 0; 111 112 // do the preparation 113 RETURN_ON_ERROR(m_spPrepare->Prepare((unsigned char *) pInputData, nInputBytes, &m_wfeInput, m_spDataX, m_spDataY, 114 &nCRC, pSpecialCodes, &m_nPeakLevel)) 115 116 // store the CRC 117 RETURN_ON_ERROR(m_spBitArray->EncodeUnsignedLong(nCRC)) 118 119 // store any special codes 120 if (*pSpecialCodes != 0) 121 { 122 RETURN_ON_ERROR(m_spBitArray->EncodeUnsignedLong(*pSpecialCodes)) 123 } 124 125 return 0; 126} 127