2 #include "APECompressCore.h"
6 #include "NewPredictor.h"
8 CAPECompressCore::CAPECompressCore(CIO
* pIO
, const WAVEFORMATEX
* pwfeInput
, int nMaxFrameBlocks
, int nCompressionLevel
)
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
));
18 memcpy(&m_wfeInput
, pwfeInput
, sizeof(WAVEFORMATEX
));
22 CAPECompressCore::~CAPECompressCore()
26 int CAPECompressCore::EncodeFrame(const void * pInputData
, int nInputBytes
)
29 const int nInputBlocks
= nInputBytes
/ m_wfeInput
.nBlockAlign
;
30 int nSpecialCodes
= 0;
32 // always start a new frame on a byte boundary
33 m_spBitArray
->AdvanceToByteBoundary();
35 // do the preparation stage
36 RETURN_ON_ERROR(Prepare(pInputData
, nInputBytes
, &nSpecialCodes
))
38 m_spPredictorX
->Flush();
39 m_spPredictorY
->Flush();
41 m_spBitArray
->FlushState(m_BitArrayStateX
);
42 m_spBitArray
->FlushState(m_BitArrayStateY
);
44 m_spBitArray
->FlushBitArray();
46 if (m_wfeInput
.nChannels
== 2)
51 if ((nSpecialCodes
& SPECIAL_FRAME_LEFT_SILENCE
) &&
52 (nSpecialCodes
& SPECIAL_FRAME_RIGHT_SILENCE
))
58 if (nSpecialCodes
& SPECIAL_FRAME_PSEUDO_STEREO
)
63 if (bEncodeX
&& bEncodeY
)
66 for (int z
= 0; z
< nInputBlocks
; z
++)
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
);
71 nLastX
= m_spDataX
[z
];
76 for (int z
= 0; z
< nInputBlocks
; z
++)
78 RETURN_ON_ERROR(m_spBitArray
->EncodeValue(m_spPredictorX
->CompressValue(m_spDataX
[z
]), m_BitArrayStateX
))
83 for (int z
= 0; z
< nInputBlocks
; z
++)
85 RETURN_ON_ERROR(m_spBitArray
->EncodeValue(m_spPredictorY
->CompressValue(m_spDataY
[z
]), m_BitArrayStateY
))
89 else if (m_wfeInput
.nChannels
== 1)
91 if (!(nSpecialCodes
& SPECIAL_FRAME_MONO_SILENCE
))
93 for (int z
= 0; z
< nInputBlocks
; z
++)
95 RETURN_ON_ERROR(m_spBitArray
->EncodeValue(m_spPredictorX
->CompressValue(m_spDataX
[z
]), m_BitArrayStateX
))
100 m_spBitArray
->Finalize();
106 int CAPECompressCore::Prepare(const void * pInputData
, int nInputBytes
, int * pSpecialCodes
)
110 unsigned int nCRC
= 0;
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
))
117 RETURN_ON_ERROR(m_spBitArray
->EncodeUnsignedLong(nCRC
))
119 // store any special codes
120 if (*pSpecialCodes
!= 0)
122 RETURN_ON_ERROR(m_spBitArray
->EncodeUnsignedLong(*pSpecialCodes
))