2 #include "APECompress.h"
3 #include IO_HEADER_FILE
4 #include "APECompressCreate.h"
5 #include "WAVInputSource.h"
7 CAPECompress::CAPECompress()
12 m_bBufferLocked
= FALSE
;
13 m_bOwnsOutputIO
= FALSE
;
16 m_spAPECompressCreate
.Assign(new CAPECompressCreate());
21 CAPECompress::~CAPECompress()
23 SAFE_ARRAY_DELETE(m_pBuffer
)
27 SAFE_DELETE(m_pioOutput
)
31 int CAPECompress::Start(const wchar_t * pOutputFilename
, const WAVEFORMATEX
* pwfeInput
, int nMaxAudioBytes
, int nCompressionLevel
, const void * pHeaderData
, int nHeaderBytes
)
33 m_pioOutput
= new IO_CLASS_NAME
;
34 m_bOwnsOutputIO
= TRUE
;
36 if (m_pioOutput
->Create(pOutputFilename
) != 0)
38 return ERROR_INVALID_OUTPUT_FILE
;
41 m_spAPECompressCreate
->Start(m_pioOutput
, pwfeInput
, nMaxAudioBytes
, nCompressionLevel
,
42 pHeaderData
, nHeaderBytes
);
44 SAFE_ARRAY_DELETE(m_pBuffer
)
45 m_nBufferSize
= m_spAPECompressCreate
->GetFullFrameBytes();
46 m_pBuffer
= new unsigned char [m_nBufferSize
];
47 memcpy(&m_wfeInput
, pwfeInput
, sizeof(WAVEFORMATEX
));
52 int CAPECompress::StartEx(CIO
* pioOutput
, const WAVEFORMATEX
* pwfeInput
, int nMaxAudioBytes
, int nCompressionLevel
, const void * pHeaderData
, int nHeaderBytes
)
54 m_pioOutput
= pioOutput
;
55 m_bOwnsOutputIO
= FALSE
;
57 m_spAPECompressCreate
->Start(m_pioOutput
, pwfeInput
, nMaxAudioBytes
, nCompressionLevel
,
58 pHeaderData
, nHeaderBytes
);
60 SAFE_ARRAY_DELETE(m_pBuffer
)
61 m_nBufferSize
= m_spAPECompressCreate
->GetFullFrameBytes();
62 m_pBuffer
= new unsigned char [m_nBufferSize
];
63 memcpy(&m_wfeInput
, pwfeInput
, sizeof(WAVEFORMATEX
));
68 int CAPECompress::GetBufferBytesAvailable()
70 return m_nBufferSize
- m_nBufferTail
;
73 int CAPECompress::UnlockBuffer(int nBytesAdded
, BOOL bProcess
)
75 if (m_bBufferLocked
== FALSE
)
76 return ERROR_UNDEFINED
;
78 m_nBufferTail
+= nBytesAdded
;
79 m_bBufferLocked
= FALSE
;
83 int nRetVal
= ProcessBuffer();
84 if (nRetVal
!= 0) { return nRetVal
; }
90 unsigned char * CAPECompress::LockBuffer(int * pBytesAvailable
)
92 if (m_pBuffer
== NULL
) { return NULL
; }
97 m_bBufferLocked
= TRUE
;
100 *pBytesAvailable
= GetBufferBytesAvailable();
102 return &m_pBuffer
[m_nBufferTail
];
105 int CAPECompress::AddData(unsigned char * pData
, int nBytes
)
107 if (m_pBuffer
== NULL
) return ERROR_INSUFFICIENT_MEMORY
;
111 while (nBytesDone
< nBytes
)
114 int nBytesAvailable
= 0;
115 unsigned char * pBuffer
= LockBuffer(&nBytesAvailable
);
116 if (pBuffer
== NULL
|| nBytesAvailable
<= 0)
117 return ERROR_UNDEFINED
;
119 // calculate how many bytes to copy and add that much to the buffer
120 int nBytesToProcess
= min(nBytesAvailable
, nBytes
- nBytesDone
);
121 memcpy(pBuffer
, &pData
[nBytesDone
], nBytesToProcess
);
123 // unlock the buffer (fail if not successful)
124 int nRetVal
= UnlockBuffer(nBytesToProcess
);
125 if (nRetVal
!= ERROR_SUCCESS
)
128 // update our progress
129 nBytesDone
+= nBytesToProcess
;
132 return ERROR_SUCCESS
;
135 int CAPECompress::Finish(unsigned char * pTerminatingData
, int nTerminatingBytes
, int nWAVTerminatingBytes
)
137 RETURN_ON_ERROR(ProcessBuffer(TRUE
))
138 return m_spAPECompressCreate
->Finish(pTerminatingData
, nTerminatingBytes
, nWAVTerminatingBytes
);
141 int CAPECompress::Kill()
143 return ERROR_SUCCESS
;
146 int CAPECompress::ProcessBuffer(BOOL bFinalize
)
148 if (m_pBuffer
== NULL
) { return ERROR_UNDEFINED
; }
152 // process as much as possible
153 int nThreshold
= (bFinalize
) ? 0 : m_spAPECompressCreate
->GetFullFrameBytes();
155 while ((m_nBufferTail
- m_nBufferHead
) >= nThreshold
)
157 int nFrameBytes
= min(m_spAPECompressCreate
->GetFullFrameBytes(), m_nBufferTail
- m_nBufferHead
);
159 if (nFrameBytes
== 0)
162 int nRetVal
= m_spAPECompressCreate
->EncodeFrame(&m_pBuffer
[m_nBufferHead
], nFrameBytes
);
163 if (nRetVal
!= 0) { return nRetVal
; }
165 m_nBufferHead
+= nFrameBytes
;
169 if (m_nBufferHead
!= 0)
171 int nBytesLeft
= m_nBufferTail
- m_nBufferHead
;
174 memmove(m_pBuffer
, &m_pBuffer
[m_nBufferHead
], nBytesLeft
);
176 m_nBufferTail
-= m_nBufferHead
;
182 return ERROR_UNDEFINED
;
185 return ERROR_SUCCESS
;
188 int CAPECompress::AddDataFromInputSource(CInputSource
* pInputSource
, int nMaxBytes
, int * pBytesAdded
)
190 // error check the parameters
191 if (pInputSource
== NULL
) return ERROR_BAD_PARAMETER
;
194 if (pBytesAdded
) *pBytesAdded
= 0;
197 int nBytesAvailable
= 0;
198 unsigned char * pBuffer
= LockBuffer(&nBytesAvailable
);
199 if ((pBuffer
== NULL
) || (nBytesAvailable
== 0))
200 return ERROR_INSUFFICIENT_MEMORY
;
202 // calculate the 'ideal' number of bytes
203 unsigned int nBytesRead
= 0;
205 int nIdealBytes
= m_spAPECompressCreate
->GetFullFrameBytes() - (m_nBufferTail
- m_nBufferHead
);
209 int nBytesToAdd
= nBytesAvailable
;
213 if (nBytesToAdd
> nMaxBytes
) nBytesToAdd
= nMaxBytes
;
216 if (nBytesToAdd
> nIdealBytes
) nBytesToAdd
= nIdealBytes
;
218 // always make requests along block boundaries
219 while ((nBytesToAdd
% m_wfeInput
.nBlockAlign
) != 0)
222 int nBlocksToAdd
= nBytesToAdd
/ m_wfeInput
.nBlockAlign
;
225 int nBlocksAdded
= 0;
226 int nRetVal
= pInputSource
->GetData(pBuffer
, nBlocksToAdd
, &nBlocksAdded
);
228 return ERROR_IO_READ
;
230 nBytesRead
= (nBlocksAdded
* m_wfeInput
.nBlockAlign
);
232 // store the bytes read
234 *pBytesAdded
= nBytesRead
;
237 // unlock the data and process
238 int nRetVal
= UnlockBuffer(nBytesRead
, TRUE
);
244 return ERROR_SUCCESS
;