1 /*****************************************************************************************
2 Monkey's Audio MACLib.h (include for using MACLib.lib in your projects)
3 Copyright (C) 2000-2003 by Matthew T. Ashland All Rights Reserved.
7 There are two main interfaces... create one (using CreateIAPExxx) and go to town:
9 IAPECompress - for creating APE files
10 IAPEDecompress - for decompressing and analyzing APE files
14 Unless otherwise specified, functions return ERROR_SUCCESS (0) on success and an
15 error code on failure.
17 The terminology "Sample" refers to a single sample value, and "Block" refers
18 to a collection of "Channel" samples. For simplicity, MAC typically uses blocks
19 everywhere so that channel mis-alignment cannot happen. (i.e. on a CD, a sample is
20 2 bytes and a block is 4 bytes ([2 bytes per sample] * [2 channels] = 4 bytes))
22 Questions / Suggestions:
24 Please direct questions or comments to the Monkey's Audio developers board:
25 http://www.monkeysaudio.com/cgi-bin/YaBB/YaBB.cgi -> Developers
26 or, if necessary, matt @ monkeysaudio.com
27 *****************************************************************************************/
32 /*************************************************************************************************
33 APE File Format Overview: (pieces in order -- only valid for the latest version APE files)
35 JUNK - any amount of "junk" before the APE_DESCRIPTOR (so people that put ID3v2 tags on the files aren't hosed)
36 APE_DESCRIPTOR - defines the sizes (and offsets) of all the pieces, as well as the MD5 checksum
37 APE_HEADER - describes all of the necessary information about the APE file
38 SEEK TABLE - the table that represents seek offsets [optional]
39 HEADER DATA - the pre-audio data from the original file [optional]
40 APE FRAMES - the actual compressed audio (broken into frames for seekability)
41 TERMINATING DATA - the post-audio data from the original file [optional]
42 TAG - describes all the properties of the file [optional]
48 This block may not be supported in the future, so don't write any software that adds meta data
49 before the APE_DESCRIPTOR. Please use the APE Tag for any meta data.
53 A 32-bit unsigned integer array of offsets from the header to the frame data. May become "delta"
54 values someday to better suit huge files.
58 Since the header is the last part written to an APE file, you must calculate the MD5 checksum out of order.
59 So, you first calculate from the tail of the seek table to the end of the terminating data.
60 Then, go back and do from the end of the descriptor to the tail of the seek table.
61 You may wish to just cache the header data when starting and run it last, so you don't
62 need to seek back in the I/O.
63 *************************************************************************************************/
65 #include "NoWindows.h"
68 /*****************************************************************************************
70 *****************************************************************************************/
71 #define COMPRESSION_LEVEL_FAST 1000
72 #define COMPRESSION_LEVEL_NORMAL 2000
73 #define COMPRESSION_LEVEL_HIGH 3000
74 #define COMPRESSION_LEVEL_EXTRA_HIGH 4000
75 #define COMPRESSION_LEVEL_INSANE 5000
77 #define MAC_FORMAT_FLAG_8_BIT 1 // is 8-bit [OBSOLETE]
78 #define MAC_FORMAT_FLAG_CRC 2 // uses the new CRC32 error detection [OBSOLETE]
79 #define MAC_FORMAT_FLAG_HAS_PEAK_LEVEL 4 // uint32 nPeakLevel after the header [OBSOLETE]
80 #define MAC_FORMAT_FLAG_24_BIT 8 // is 24-bit [OBSOLETE]
81 #define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS 16 // has the number of seek elements after the peak level
82 #define MAC_FORMAT_FLAG_CREATE_WAV_HEADER 32 // create the wave header on decompression (not stored)
84 #define CREATE_WAV_HEADER_ON_DECOMPRESSION -1
85 #define MAX_AUDIO_BYTES_UNKNOWN -1
87 typedef void (__stdcall
* APE_PROGRESS_CALLBACK
) (int);
89 /*****************************************************************************************
91 *****************************************************************************************/
96 unsigned int nRIFFBytes
;
102 char cFormatHeader
[4];
103 unsigned int nFormatBytes
;
105 unsigned short nFormatTag
;
106 unsigned short nChannels
;
107 unsigned int nSamplesPerSec
;
108 unsigned int nAvgBytesPerSec
;
109 unsigned short nBlockAlign
;
110 unsigned short nBitsPerSample
;
114 unsigned int nDataBytes
;
117 /*****************************************************************************************
118 APE_DESCRIPTOR structure (file header that describes lengths, offsets, etc.)
119 *****************************************************************************************/
120 struct APE_DESCRIPTOR
122 char cID
[4]; // should equal 'MAC '
123 uint16 nVersion
; // version number * 1000 (3.81 = 3810)
125 uint32 nDescriptorBytes
; // the number of descriptor bytes (allows later expansion of this header)
126 uint32 nHeaderBytes
; // the number of header APE_HEADER bytes
127 uint32 nSeekTableBytes
; // the number of bytes of the seek table
128 uint32 nHeaderDataBytes
; // the number of header data bytes (from original file)
129 uint32 nAPEFrameDataBytes
; // the number of bytes of APE frame data
130 uint32 nAPEFrameDataBytesHigh
; // the high order number of APE frame data bytes
131 uint32 nTerminatingDataBytes
; // the terminating data of the file (not including tag data)
133 uint8 cFileMD5
[16]; // the MD5 hash of the file (see notes for usage... it's a littly tricky)
136 /*****************************************************************************************
137 APE_HEADER structure (describes the format, duration, etc. of the APE file)
138 *****************************************************************************************/
141 uint16 nCompressionLevel
; // the compression level (see defines I.E. COMPRESSION_LEVEL_FAST)
142 uint16 nFormatFlags
; // any format flags (for future use)
144 uint32 nBlocksPerFrame
; // the number of audio blocks in one frame
145 uint32 nFinalFrameBlocks
; // the number of audio blocks in the final frame
146 uint32 nTotalFrames
; // the total number of frames
148 uint16 nBitsPerSample
; // the bits per sample (typically 16)
149 uint16 nChannels
; // the number of channels (1 or 2)
150 uint32 nSampleRate
; // the sample rate (typically 44100)
153 /*************************************************************************************************
154 Classes (fully defined elsewhere)
155 *************************************************************************************************/
160 /*************************************************************************************************
161 IAPEDecompress fields - used when querying for information
164 -the distinction between APE_INFO_XXXX and APE_DECOMPRESS_XXXX is that the first is querying the APE
165 information engine, and the other is querying the decompressor, and since the decompressor can be
166 a range of an APE file (for APL), differences will arise. Typically, use the APE_DECOMPRESS_XXXX
167 fields when querying for info about the length, etc. so APL will work properly.
168 (i.e. (APE_INFO_TOTAL_BLOCKS != APE_DECOMPRESS_TOTAL_BLOCKS) for APL files)
169 *************************************************************************************************/
170 enum APE_DECOMPRESS_FIELDS
172 APE_INFO_FILE_VERSION
= 1000, // version of the APE file * 1000 (3.93 = 3930) [ignored, ignored]
173 APE_INFO_COMPRESSION_LEVEL
= 1001, // compression level of the APE file [ignored, ignored]
174 APE_INFO_FORMAT_FLAGS
= 1002, // format flags of the APE file [ignored, ignored]
175 APE_INFO_SAMPLE_RATE
= 1003, // sample rate (Hz) [ignored, ignored]
176 APE_INFO_BITS_PER_SAMPLE
= 1004, // bits per sample [ignored, ignored]
177 APE_INFO_BYTES_PER_SAMPLE
= 1005, // number of bytes per sample [ignored, ignored]
178 APE_INFO_CHANNELS
= 1006, // channels [ignored, ignored]
179 APE_INFO_BLOCK_ALIGN
= 1007, // block alignment [ignored, ignored]
180 APE_INFO_BLOCKS_PER_FRAME
= 1008, // number of blocks in a frame (frames are used internally) [ignored, ignored]
181 APE_INFO_FINAL_FRAME_BLOCKS
= 1009, // blocks in the final frame (frames are used internally) [ignored, ignored]
182 APE_INFO_TOTAL_FRAMES
= 1010, // total number frames (frames are used internally) [ignored, ignored]
183 APE_INFO_WAV_HEADER_BYTES
= 1011, // header bytes of the decompressed WAV [ignored, ignored]
184 APE_INFO_WAV_TERMINATING_BYTES
= 1012, // terminating bytes of the decompressed WAV [ignored, ignored]
185 APE_INFO_WAV_DATA_BYTES
= 1013, // data bytes of the decompressed WAV [ignored, ignored]
186 APE_INFO_WAV_TOTAL_BYTES
= 1014, // total bytes of the decompressed WAV [ignored, ignored]
187 APE_INFO_APE_TOTAL_BYTES
= 1015, // total bytes of the APE file [ignored, ignored]
188 APE_INFO_TOTAL_BLOCKS
= 1016, // total blocks of audio data [ignored, ignored]
189 APE_INFO_LENGTH_MS
= 1017, // length in ms (1 sec = 1000 ms) [ignored, ignored]
190 APE_INFO_AVERAGE_BITRATE
= 1018, // average bitrate of the APE [ignored, ignored]
191 APE_INFO_FRAME_BITRATE
= 1019, // bitrate of specified APE frame [frame index, ignored]
192 APE_INFO_DECOMPRESSED_BITRATE
= 1020, // bitrate of the decompressed WAV [ignored, ignored]
193 APE_INFO_PEAK_LEVEL
= 1021, // peak audio level (obsolete) (-1 is unknown) [ignored, ignored]
194 APE_INFO_SEEK_BIT
= 1022, // bit offset [frame index, ignored]
195 APE_INFO_SEEK_BYTE
= 1023, // byte offset [frame index, ignored]
196 APE_INFO_WAV_HEADER_DATA
= 1024, // error code [buffer *, max bytes]
197 APE_INFO_WAV_TERMINATING_DATA
= 1025, // error code [buffer *, max bytes]
198 APE_INFO_WAVEFORMATEX
= 1026, // error code [waveformatex *, ignored]
199 APE_INFO_IO_SOURCE
= 1027, // I/O source (CIO *) [ignored, ignored]
200 APE_INFO_FRAME_BYTES
= 1028, // bytes (compressed) of the frame [frame index, ignored]
201 APE_INFO_FRAME_BLOCKS
= 1029, // blocks in a given frame [frame index, ignored]
202 APE_INFO_TAG
= 1030, // point to tag (CAPETag *) [ignored, ignored]
204 APE_DECOMPRESS_CURRENT_BLOCK
= 2000, // current block location [ignored, ignored]
205 APE_DECOMPRESS_CURRENT_MS
= 2001, // current millisecond location [ignored, ignored]
206 APE_DECOMPRESS_TOTAL_BLOCKS
= 2002, // total blocks in the decompressors range [ignored, ignored]
207 APE_DECOMPRESS_LENGTH_MS
= 2003, // total blocks in the decompressors range [ignored, ignored]
208 APE_DECOMPRESS_CURRENT_BITRATE
= 2004, // current bitrate [ignored, ignored]
209 APE_DECOMPRESS_AVERAGE_BITRATE
= 2005, // average bitrate (works with ranges) [ignored, ignored]
211 APE_INTERNAL_INFO
= 3000, // for internal use -- don't use (returns APE_FILE_INFO *) [ignored, ignored]
214 /*************************************************************************************************
215 IAPEDecompress - interface for working with existing APE files (decoding, seeking, analyzing, etc.)
216 *************************************************************************************************/
221 // destructor (needed so implementation's destructor will be called)
222 virtual ~IAPEDecompress() {}
224 /*********************************************************************************************
226 *********************************************************************************************/
228 //////////////////////////////////////////////////////////////////////////////////////////////
229 // GetData(...) - gets raw decompressed audio
233 // a pointer to a buffer to put the data into
235 // the number of audio blocks desired (see note at intro about blocks vs. samples)
236 // int * pBlocksRetrieved
237 // the number of blocks actually retrieved (could be less at end of file or on critical failure)
238 //////////////////////////////////////////////////////////////////////////////////////////////
239 virtual int GetData(char * pBuffer
, int nBlocks
, int * pBlocksRetrieved
) = 0;
241 //////////////////////////////////////////////////////////////////////////////////////////////
246 // the block to seek to (see note at intro about blocks vs. samples)
247 //////////////////////////////////////////////////////////////////////////////////////////////
248 virtual int Seek(int nBlockOffset
) = 0;
250 /*********************************************************************************************
252 *********************************************************************************************/
254 //////////////////////////////////////////////////////////////////////////////////////////////
255 // GetInfo(...) - get information about the APE file or the state of the decompressor
258 // APE_DECOMPRESS_FIELDS Field
259 // the field we're querying (see APE_DECOMPRESS_FIELDS above for more info)
261 // generic parameter... usage is listed in APE_DECOMPRESS_FIELDS
263 // generic parameter... usage is listed in APE_DECOMPRESS_FIELDS
264 //////////////////////////////////////////////////////////////////////////////////////////////
265 virtual int GetInfo(APE_DECOMPRESS_FIELDS Field
, int nParam1
= 0, int nParam2
= 0) = 0;
268 /*************************************************************************************************
269 IAPECompress - interface for creating APE files
273 To create an APE file, you Start(...), then add data (in a variety of ways), then Finish(...)
274 *************************************************************************************************/
279 // destructor (needed so implementation's destructor will be called)
280 virtual ~IAPECompress() {}
282 /*********************************************************************************************
284 *********************************************************************************************/
286 //////////////////////////////////////////////////////////////////////////////////////////////
287 // Start(...) / StartEx(...) - starts encoding
290 // CIO * pioOutput / const str_utf16 * pFilename
291 // the output... either a filename or an I/O source
292 // WAVEFORMATEX * pwfeInput
293 // format of the audio to encode (use FillWaveFormatEx() if necessary)
294 // int nMaxAudioBytes
295 // the absolute maximum audio bytes that will be encoded... encoding fails with a
296 // ERROR_APE_COMPRESS_TOO_MUCH_DATA if you attempt to encode more than specified here
297 // (if unknown, use MAX_AUDIO_BYTES_UNKNOWN to allocate as much storage in the seek table as
298 // possible... limit is then 2 GB of data (~4 hours of CD music)... this wastes around
299 // 30kb, so only do it if completely necessary)
300 // int nCompressionLevel
301 // the compression level for the APE file (fast - extra high)
302 // (note: extra-high is much slower for little gain)
303 // const void * pHeaderData
304 // a pointer to a buffer containing the WAV header (data before the data block in the WAV)
305 // (note: use NULL for on-the-fly encoding... see next parameter)
307 // number of bytes in the header data buffer (use CREATE_WAV_HEADER_ON_DECOMPRESSION and
308 // NULL for the pHeaderData and MAC will automatically create the appropriate WAV header
310 //////////////////////////////////////////////////////////////////////////////////////////////
312 virtual int Start(const str_utf16
* pOutputFilename
, const WAVEFORMATEX
* pwfeInput
,
313 int nMaxAudioBytes
= MAX_AUDIO_BYTES_UNKNOWN
, int nCompressionLevel
= COMPRESSION_LEVEL_NORMAL
,
314 const void * pHeaderData
= NULL
, int nHeaderBytes
= CREATE_WAV_HEADER_ON_DECOMPRESSION
) = 0;
316 virtual int StartEx(CIO
* pioOutput
, const WAVEFORMATEX
* pwfeInput
,
317 int nMaxAudioBytes
= MAX_AUDIO_BYTES_UNKNOWN
, int nCompressionLevel
= COMPRESSION_LEVEL_NORMAL
,
318 const void * pHeaderData
= NULL
, int nHeaderBytes
= CREATE_WAV_HEADER_ON_DECOMPRESSION
) = 0;
320 /*********************************************************************************************
321 * Add / Compress Data
322 * - there are 3 ways to add data:
323 * 1) simple call AddData(...)
324 * 2) lock MAC's buffer, copy into it, and unlock (LockBuffer(...) / UnlockBuffer(...))
325 * 3) from an I/O source (AddDataFromInputSource(...))
326 *********************************************************************************************/
328 //////////////////////////////////////////////////////////////////////////////////////////////
329 // AddData(...) - adds data to the encoder
332 // unsigned char * pData
333 // a pointer to a buffer containing the raw audio data
335 // the number of bytes in the buffer
336 //////////////////////////////////////////////////////////////////////////////////////////////
337 virtual int AddData(unsigned char * pData
, int nBytes
) = 0;
339 //////////////////////////////////////////////////////////////////////////////////////////////
340 // GetBufferBytesAvailable(...) - returns the number of bytes available in the buffer
341 // (helpful when locking)
342 //////////////////////////////////////////////////////////////////////////////////////////////
343 virtual int GetBufferBytesAvailable() = 0;
345 //////////////////////////////////////////////////////////////////////////////////////////////
346 // LockBuffer(...) - locks MAC's buffer so we can copy into it
349 // int * pBytesAvailable
350 // returns the number of bytes available in the buffer (DO NOT COPY MORE THAN THIS IN)
353 // pointer to the buffer (add at that location)
354 //////////////////////////////////////////////////////////////////////////////////////////////
355 virtual unsigned char * LockBuffer(int * pBytesAvailable
) = 0;
357 //////////////////////////////////////////////////////////////////////////////////////////////
358 // UnlockBuffer(...) - releases the buffer
362 // the number of bytes copied into the buffer
364 // whether MAC should process as much as possible of the buffer
365 //////////////////////////////////////////////////////////////////////////////////////////////
366 virtual int UnlockBuffer(int nBytesAdded
, BOOL bProcess
= TRUE
) = 0;
369 //////////////////////////////////////////////////////////////////////////////////////////////
370 // AddDataFromInputSource(...) - use a CInputSource (input source) to add data
373 // CInputSource * pInputSource
374 // a pointer to the input source
376 // the maximum number of bytes to let MAC add (-1 if MAC can add any amount)
378 // returns the number of bytes added from the I/O source
379 //////////////////////////////////////////////////////////////////////////////////////////////
380 virtual int AddDataFromInputSource(CInputSource
* pInputSource
, int nMaxBytes
= -1, int * pBytesAdded
= NULL
) = 0;
382 /*********************************************************************************************
384 *********************************************************************************************/
386 //////////////////////////////////////////////////////////////////////////////////////////////
387 // Finish(...) - ends encoding and finalizes the file
390 // unsigned char * pTerminatingData
391 // a pointer to a buffer containing the information to place at the end of the APE file
392 // (comprised of the WAV terminating data (data after the data block in the WAV) followed
393 // by any tag information)
394 // int nTerminatingBytes
395 // number of bytes in the terminating data buffer
396 // int nWAVTerminatingBytes
397 // the number of bytes of the terminating data buffer that should be appended to a decoded
398 // WAV file (it's basically nTerminatingBytes - the bytes that make up the tag)
399 //////////////////////////////////////////////////////////////////////////////////////////////
400 virtual int Finish(unsigned char * pTerminatingData
, int nTerminatingBytes
, int nWAVTerminatingBytes
) = 0;
402 //////////////////////////////////////////////////////////////////////////////////////////////
403 // Kill(...) - stops encoding and deletes the output file
404 // --- NOT CURRENTLY IMPLEMENTED ---
405 //////////////////////////////////////////////////////////////////////////////////////////////
406 virtual int Kill() = 0;
409 /*************************************************************************************************
410 Functions to create the interfaces
413 Interface creation returns a NULL pointer on failure (and fills error code if it was passed in)
417 IAPEDecompress * pAPEDecompress = CreateIAPEDecompress("c:\\1.ape", &nErrorCode);
418 if (pAPEDecompress == NULL)
420 // failure... nErrorCode will have specific code
423 *************************************************************************************************/
426 IAPEDecompress
* __stdcall
CreateIAPEDecompress(const str_utf16
* pFilename
, int * pErrorCode
= NULL
);
427 IAPEDecompress
* __stdcall
CreateIAPEDecompressEx(CIO
* pIO
, int * pErrorCode
= NULL
);
428 IAPEDecompress
* __stdcall
CreateIAPEDecompressEx2(CAPEInfo
* pAPEInfo
, int nStartBlock
= -1, int nFinishBlock
= -1, int * pErrorCode
= NULL
);
429 IAPECompress
* __stdcall
CreateIAPECompress(int * pErrorCode
= NULL
);
432 /*************************************************************************************************
433 Simple functions - see the SDK sample projects for usage examples
434 *************************************************************************************************/
437 // process whole files
438 DLLEXPORT
int __stdcall
CompressFile(const str_ansi
* pInputFilename
, const str_ansi
* pOutputFilename
, int nCompressionLevel
= COMPRESSION_LEVEL_NORMAL
, int * pPercentageDone
= NULL
, APE_PROGRESS_CALLBACK ProgressCallback
= 0, int * pKillFlag
= NULL
);
439 DLLEXPORT
int __stdcall
DecompressFile(const str_ansi
* pInputFilename
, const str_ansi
* pOutputFilename
, int * pPercentageDone
, APE_PROGRESS_CALLBACK ProgressCallback
, int * pKillFlag
);
440 DLLEXPORT
int __stdcall
ConvertFile(const str_ansi
* pInputFilename
, const str_ansi
* pOutputFilename
, int nCompressionLevel
, int * pPercentageDone
, APE_PROGRESS_CALLBACK ProgressCallback
, int * pKillFlag
);
441 DLLEXPORT
int __stdcall
VerifyFile(const str_ansi
* pInputFilename
, int * pPercentageDone
, APE_PROGRESS_CALLBACK ProgressCallback
, int * pKillFlag
, BOOL bQuickVerifyIfPossible
);
443 DLLEXPORT
int __stdcall
CompressFileW(const str_utf16
* pInputFilename
, const str_utf16
* pOutputFilename
, int nCompressionLevel
= COMPRESSION_LEVEL_NORMAL
, int * pPercentageDone
= NULL
, APE_PROGRESS_CALLBACK ProgressCallback
= 0, int * pKillFlag
= NULL
);
444 DLLEXPORT
int __stdcall
DecompressFileW(const str_utf16
* pInputFilename
, const str_utf16
* pOutputFilename
, int * pPercentageDone
, APE_PROGRESS_CALLBACK ProgressCallback
, int * pKillFlag
);
445 DLLEXPORT
int __stdcall
ConvertFileW(const str_utf16
* pInputFilename
, const str_utf16
* pOutputFilename
, int nCompressionLevel
, int * pPercentageDone
, APE_PROGRESS_CALLBACK ProgressCallback
, int * pKillFlag
);
446 DLLEXPORT
int __stdcall
VerifyFileW(const str_utf16
* pInputFilename
, int * pPercentageDone
, APE_PROGRESS_CALLBACK ProgressCallback
, int * pKillFlag
, BOOL bQuickVerifyIfPossible
= FALSE
);
449 DLLEXPORT
int __stdcall
FillWaveFormatEx(WAVEFORMATEX
* pWaveFormatEx
, int nSampleRate
= 44100, int nBitsPerSample
= 16, int nChannels
= 2);
450 DLLEXPORT
int __stdcall
FillWaveHeader(WAVE_HEADER
* pWAVHeader
, int nAudioBytes
, WAVEFORMATEX
* pWaveFormatEx
, int nTerminatingBytes
= 0);
453 #endif // #ifndef APE_MACLIB_H