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