1 #include "All.h"
2 #include "APECompressCore.h"
3
4 #include "BitArray.h"
5 #include "Prepare.h"
6 #include "NewPredictor.h"
7
CAPECompressCore(CIO * pIO,const WAVEFORMATEX * pwfeInput,int nMaxFrameBlocks,int nCompressionLevel)8 CAPECompressCore::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
~CAPECompressCore()22 CAPECompressCore::~CAPECompressCore()
23 {
24 }
25
EncodeFrame(const void * pInputData,int nInputBytes)26 int 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
Prepare(const void * pInputData,int nInputBytes,int * pSpecialCodes)106 int 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