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