gstreamer/gst/monkeyaudio/libmonkeyaudio/MACLib.h
Jeremy Simon c1a4db611b Add monkeyaudio plugin
Original commit message from CVS:
Add monkeyaudio plugin
2003-03-11 19:33:32 +00:00

393 lines
21 KiB
C++

/*****************************************************************************************
Monkey's Audio MACLib.h (include for using MACLib.lib in your projects)
Copyright (C) 2000-2002 by Matthew T. Ashland All Rights Reserved.
Overview:
There are two main interfaces... create one (using CreateIAPExxx) and go to town:
IAPECompress - for creating APE files
IAPEDecompress - for decompressing and analyzing APE files
Note(s):
-unless otherwise specified, functions return ERROR_SUCCESS (0) on success and an
error code on failure.
-the terminology "Sample" refers to a single sample value, and "Block" refers
to a collection of "Channel" samples. For simplicity, MAC typically uses blocks
everywhere so that channel mis-alignment cannot happen. (i.e. on a CD, a sample is
2 bytes and a block is 4 bytes ([2 bytes / sample] * [2 channels] = 4 bytes))
Questions / Suggestions:
Please direct questions or comments to the Monkey's Audio developers board:
http://www.monkeysaudio.com/cgi-bin/YaBB/YaBB.cgi -> Developers
or, if necessary, email @ monkeysaudio.com
*****************************************************************************************/
#ifndef APE_MACLIB_H
#define APE_MACLIB_H
/*****************************************************************************************
Defines
*****************************************************************************************/
#define COMPRESSION_LEVEL_FAST 1000
#define COMPRESSION_LEVEL_NORMAL 2000
#define COMPRESSION_LEVEL_HIGH 3000
#define COMPRESSION_LEVEL_EXTRA_HIGH 4000
#define COMPRESSION_LEVEL_INSANE_HIGH 5000
#define COMPRESSION_LEVEL_BRAINDEAD_HIGH 6000
#define MAC_FORMAT_FLAG_8_BIT 1 // is 8-bit
#define MAC_FORMAT_FLAG_CRC 2 // uses the new CRC32 error detection
#define MAC_FORMAT_FLAG_HAS_PEAK_LEVEL 4 // unsigned __int32 Peak_Level after the header
#define MAC_FORMAT_FLAG_24_BIT 8 // is 24-bit
#define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS 16 // has the number of seek elements after the peak level
#define MAC_FORMAT_FLAG_CREATE_WAV_HEADER 32 // create the wave header on decompression (not stored)
#define CREATE_WAV_HEADER_ON_DECOMPRESSION -1
#define MAX_AUDIO_BYTES_UNKNOWN -1
typedef void (__stdcall * APE_PROGRESS_CALLBACK) (int);
/*****************************************************************************************
WAV header structure
*****************************************************************************************/
struct WAVE_HEADER
{
// RIFF header
char cRIFFHeader[4];
unsigned int nRIFFBytes;
// data type
char cDataTypeID[4];
// wave format
char cFormatHeader[4];
unsigned int nFormatBytes;
unsigned short nFormatTag;
unsigned short nChannels;
unsigned int nSamplesPerSec;
unsigned int nAvgBytesPerSec;
unsigned short nBlockAlign;
unsigned short nBitsPerSample;
// data chunk header
char cDataHeader[4];
unsigned int nDataBytes;
};
/*****************************************************************************************
APE header structure (what's at the front of an APE file)
*****************************************************************************************/
#define APE_HEADER_BYTES 32
struct APE_HEADER
{
char cID[4]; // should equal 'MAC '
unsigned __int16 nVersion; // version number * 1000 (3.81 = 3810)
unsigned __int16 nCompressionLevel; // the compression level
unsigned __int16 nFormatFlags; // any format flags (for future use)
unsigned __int16 nChannels; // the number of channels (1 or 2)
unsigned __int32 nSampleRate; // the sample rate (typically 44100)
unsigned __int32 nHeaderBytes; // the bytes after the MAC header that compose the WAV header
unsigned __int32 nTerminatingBytes; // the bytes after that raw data (for extended info)
unsigned __int32 nTotalFrames; // the number of frames in the file
unsigned __int32 nFinalFrameBlocks; // the number of samples in the final frame
};
/*************************************************************************************************
Classes (fully defined elsewhere)
*************************************************************************************************/
class CIO;
class CInputSource;
/*************************************************************************************************
IAPEDecompress fields - used when querying for information
Note(s):
-the distinction between APE_INFO_XXXX and APE_DECOMPRESS_XXXX is that the first is querying the APE
information engine, and the other is querying the decompressor, and since the decompressor can be
a range of an APE file (for APL), differences will arise. Typically, use the APE_DECOMPRESS_XXXX
fields when querying for info about the length, etc. so APL will work properly.
(i.e. (APE_INFO_TOTAL_BLOCKS != APE_DECOMPRESS_TOTAL_BLOCKS) for APL files)
*************************************************************************************************/
enum APE_DECOMPRESS_FIELDS
{
APE_INFO_FILE_VERSION = 1000, // version of the APE file * 1000 (3.93 = 3930) [ignored, ignored]
APE_INFO_COMPRESSION_LEVEL = 1001, // compression level of the APE file [ignored, ignored]
APE_INFO_FORMAT_FLAGS = 1002, // format flags of the APE file [ignored, ignored]
APE_INFO_SAMPLE_RATE = 1003, // sample rate (Hz) [ignored, ignored]
APE_INFO_BITS_PER_SAMPLE = 1004, // bits per sample [ignored, ignored]
APE_INFO_BYTES_PER_SAMPLE = 1005, // number of bytes per sample [ignored, ignored]
APE_INFO_CHANNELS = 1006, // channels [ignored, ignored]
APE_INFO_BLOCK_ALIGN = 1007, // block alignment [ignored, ignored]
APE_INFO_BLOCKS_PER_FRAME = 1008, // number of blocks in a frame (frames are used internally) [ignored, ignored]
APE_INFO_FINAL_FRAME_BLOCKS = 1009, // blocks in the final frame (frames are used internally) [ignored, ignored]
APE_INFO_TOTAL_FRAMES = 1010, // total number frames (frames are used internally) [ignored, ignored]
APE_INFO_WAV_HEADER_BYTES = 1011, // header bytes of the decompressed WAV [ignored, ignored]
APE_INFO_WAV_TERMINATING_BYTES = 1012, // terminating bytes of the decompressed WAV [ignored, ignored]
APE_INFO_WAV_DATA_BYTES = 1013, // data bytes of the decompressed WAV [ignored, ignored]
APE_INFO_WAV_TOTAL_BYTES = 1014, // total bytes of the decompressed WAV [ignored, ignored]
APE_INFO_APE_TOTAL_BYTES = 1015, // total bytes of the APE file [ignored, ignored]
APE_INFO_TOTAL_BLOCKS = 1016, // total blocks of audio data [ignored, ignored]
APE_INFO_LENGTH_MS = 1017, // length in ms (1 sec = 1000 ms) [ignored, ignored]
APE_INFO_AVERAGE_BITRATE = 1018, // average bitrate of the APE [ignored, ignored]
APE_INFO_FRAME_BITRATE = 1019, // bitrate of specified APE frame [frame index, ignored]
APE_INFO_DECOMPRESSED_BITRATE = 1020, // bitrate of the decompressed WAV [ignored, ignored]
APE_INFO_PEAK_LEVEL = 1021, // peak audio level (-1 is unknown) [ignored, ignored]
APE_INFO_SEEK_BIT = 1022, // bit offset [frame index, ignored]
APE_INFO_SEEK_BYTE = 1023, // byte offset [frame index, ignored]
APE_INFO_WAV_HEADER_DATA = 1024, // error code [buffer *, max bytes]
APE_INFO_WAV_TERMINATING_DATA = 1025, // error code [buffer *, max bytes]
APE_INFO_WAVEFORMATEX = 1026, // error code [waveformatex *, ignored]
APE_INFO_IO_SOURCE = 1027, // I/O source (CIO *) [ignored, ignored]
APE_INFO_FRAME_BYTES = 1028, // bytes (compressed) of the frame [frame index, ignored]
APE_INFO_FRAME_BLOCKS = 1029, // blocks in a given frame [frame index, ignored]
APE_INFO_TAG = 1030, // point to tag (CAPETag *) [ignored, ignored]
APE_DECOMPRESS_CURRENT_BLOCK = 2000, // current block location [ignored, ignored]
APE_DECOMPRESS_CURRENT_MS = 2001, // current millisecond location [ignored, ignored]
APE_DECOMPRESS_TOTAL_BLOCKS = 2002, // total blocks in the decompressors range [ignored, ignored]
APE_DECOMPRESS_LENGTH_MS = 2003, // total blocks in the decompressors range [ignored, ignored]
APE_DECOMPRESS_CURRENT_BITRATE = 2004, // current bitrate [ignored, ignored]
APE_DECOMPRESS_AVERAGE_BITRATE = 2005 // average bitrate (works with ranges) [ignored, ignored]
};
/*************************************************************************************************
IAPEDecompress - interface for working with existing APE files (decoding, seeking, analyzing, etc.)
*************************************************************************************************/
class IAPEDecompress
{
public:
// destructor (needed so implementation's destructor will be called)
virtual ~IAPEDecompress() {}
/*********************************************************************************************
* Decompress / Seek
*********************************************************************************************/
//////////////////////////////////////////////////////////////////////////////////////////////
// GetData(...) - gets raw decompressed audio
//
// Parameters:
// char * pBuffer
// a pointer to a buffer to put the data into
// int nBlocks
// the number of audio blocks desired (see note at intro about blocks vs. samples)
// int * pBlocksRetrieved
// the number of blocks actually retrieved (could be less at end of file or on critical failure)
//////////////////////////////////////////////////////////////////////////////////////////////
virtual int GetData(char * pBuffer, int nBlocks, int * pBlocksRetrieved) = 0;
//////////////////////////////////////////////////////////////////////////////////////////////
// Seek(...) - seeks
//
// Parameters:
// int nBlockOffset
// the block to seek to (see note at intro about blocks vs. samples)
//////////////////////////////////////////////////////////////////////////////////////////////
virtual int Seek(int nBlockOffset) = 0;
/*********************************************************************************************
* Get Information
*********************************************************************************************/
//////////////////////////////////////////////////////////////////////////////////////////////
// GetInfo(...) - get information about the APE file or the state of the decompressor
//
// Parameters:
// APE_DECOMPRESS_FIELDS Field
// the field we're querying (see APE_DECOMPRESS_FIELDS above for more info)
// int nParam1
// generic parameter... usage is listed in APE_DECOMPRESS_FIELDS
// int nParam2
// generic parameter... usage is listed in APE_DECOMPRESS_FIELDS
//////////////////////////////////////////////////////////////////////////////////////////////
virtual int GetInfo(APE_DECOMPRESS_FIELDS Field, int nParam1 = 0, int nParam2 = 0) = 0;
};
/*************************************************************************************************
IAPECompress - interface for creating APE files
Usage:
To create an APE file, you Start(...), then add data (in a variety of ways), then Finish(...)
*************************************************************************************************/
class IAPECompress
{
public:
// destructor (needed so implementation's destructor will be called)
virtual ~IAPECompress() {}
/*********************************************************************************************
* Start
*********************************************************************************************/
//////////////////////////////////////////////////////////////////////////////////////////////
// Start(...) / StartEx(...) - starts encoding
//
// Parameters:
// CIO * pioOutput / const char * pFilename
// the output... either a filename or an I/O source
// WAVEFORMATEX * pwfeInput
// format of the audio to encode (use FillWaveFormatEx() if necessary)
// int nMaxAudioBytes
// the absolute maximum audio bytes that will be encoded... encoding fails with a
// ERROR_APE_COMPRESS_TOO_MUCH_DATA if you attempt to encode more than specified here
// (if unknown, use MAX_AUDIO_BYTES_UNKNOWN to allocate as much storage in the seek table as
// possible... limit is then 2 GB of data (~4 hours of CD music)... this wastes around
// 30kb, so only do it if completely necessary)
// int nCompressionLevel
// the compression level for the APE file (fast - extra high)
// (note: extra-high is much slower for little gain)
// const unsigned char * pHeaderData
// a pointer to a buffer containing the WAV header (data before the data block in the WAV)
// (note: use NULL for on-the-fly encoding... see next parameter)
// int nHeaderBytes
// number of bytes in the header data buffer (use CREATE_WAV_HEADER_ON_DECOMPRESSION and
// NULL for the pHeaderData and MAC will automatically create the appropriate WAV header
// on decompression)
//////////////////////////////////////////////////////////////////////////////////////////////
virtual int Start(const char * pOutputFilename, const WAVEFORMATEX * pwfeInput,
int nMaxAudioBytes = MAX_AUDIO_BYTES_UNKNOWN, int nCompressionLevel = COMPRESSION_LEVEL_NORMAL,
const unsigned char * pHeaderData = NULL, int nHeaderBytes = CREATE_WAV_HEADER_ON_DECOMPRESSION) = 0;
virtual int StartEx(CIO * pioOutput, const WAVEFORMATEX * pwfeInput,
int nMaxAudioBytes = MAX_AUDIO_BYTES_UNKNOWN, int nCompressionLevel = COMPRESSION_LEVEL_NORMAL,
const unsigned char * pHeaderData = NULL, int nHeaderBytes = CREATE_WAV_HEADER_ON_DECOMPRESSION) = 0;
/*********************************************************************************************
* Add / Compress Data
* - there are 3 ways to add data:
* 1) simple call AddData(...)
* 2) lock MAC's buffer, copy into it, and unlock (LockBuffer(...) / UnlockBuffer(...))
* 3) from an I/O source (AddDataFromInputSource(...))
*********************************************************************************************/
//////////////////////////////////////////////////////////////////////////////////////////////
// AddData(...) - adds data to the encoder
//
// Parameters:
// unsigned char * pData
// a pointer to a buffer containing the raw audio data
// int nBytes
// the number of bytes in the buffer
//////////////////////////////////////////////////////////////////////////////////////////////
virtual int AddData(unsigned char * pData, int nBytes) = 0;
//////////////////////////////////////////////////////////////////////////////////////////////
// GetBufferBytesAvailable(...) - returns the number of bytes available in the buffer
// (helpful when locking)
//////////////////////////////////////////////////////////////////////////////////////////////
virtual int GetBufferBytesAvailable() = 0;
//////////////////////////////////////////////////////////////////////////////////////////////
// LockBuffer(...) - locks MAC's buffer so we can copy into it
//
// Parameters:
// int * pBytesAvailable
// returns the number of bytes available in the buffer (DO NOT COPY MORE THAN THIS IN)
//
// Return:
// pointer to the buffer (add at that location)
//////////////////////////////////////////////////////////////////////////////////////////////
virtual unsigned char * LockBuffer(int * pBytesAvailable) = 0;
//////////////////////////////////////////////////////////////////////////////////////////////
// UnlockBuffer(...) - releases the buffer
//
// Parameters:
// int nBytesAdded
// the number of bytes copied into the buffer
// BOOL bProcess
// whether MAC should process as much as possible of the buffer
//////////////////////////////////////////////////////////////////////////////////////////////
virtual int UnlockBuffer(int nBytesAdded, BOOL bProcess = TRUE) = 0;
//////////////////////////////////////////////////////////////////////////////////////////////
// AddDataFromInputSource(...) - use a CInputSource (input source) to add data
//
// Parameters:
// CInputSource * pInputSource
// a pointer to the input source
// int nMaxBytes
// the maximum number of bytes to let MAC add (-1 if MAC can add any amount)
// int * pBytesAdded
// returns the number of bytes added from the I/O source
//////////////////////////////////////////////////////////////////////////////////////////////
virtual int AddDataFromInputSource(CInputSource * pInputSource, int nMaxBytes = -1, int * pBytesAdded = NULL) = 0;
/*********************************************************************************************
* Finish / Kill
*********************************************************************************************/
//////////////////////////////////////////////////////////////////////////////////////////////
// Finish(...) - ends encoding and finalizes the file
//
// Parameters:
// unsigned char * pTerminatingData
// a pointer to a buffer containing the information to place at the end of the APE file
// (comprised of the WAV terminating data (data after the data block in the WAV) followed
// by any tag information)
// int nTerminatingBytes
// number of bytes in the terminating data buffer
// int nWAVTerminatingBytes
// the number of bytes of the terminating data buffer that should be appended to a decoded
// WAV file (it's basically nTerminatingBytes - the bytes that make up the tag)
//////////////////////////////////////////////////////////////////////////////////////////////
virtual int Finish(unsigned char * pTerminatingData, int nTerminatingBytes, int nWAVTerminatingBytes) = 0;
//////////////////////////////////////////////////////////////////////////////////////////////
// Kill(...) - stops encoding and deletes the output file
// --- NOT CURRENTLY IMPLEMENTED ---
//////////////////////////////////////////////////////////////////////////////////////////////
virtual int Kill() = 0;
};
/*************************************************************************************************
Functions to create the interfaces
Usage:
Interface creation returns a NULL pointer on failure (and fills error code if it was passed in)
Usage example:
int nErrorCode;
IAPEDecompress * pAPEDecompress = CreateIAPEDecompress("c:\\1.ape", &nErrorCode);
if (pAPEDecompress == NULL)
{
// failure... nErrorCode will have specific code
}
*************************************************************************************************/
extern "C"
{
IAPEDecompress * __stdcall CreateIAPEDecompress(const char * pFilename, int * pErrorCode = NULL);
IAPEDecompress * __stdcall CreateIAPEDecompressEx(CIO * pIO, int * pErrorCode = NULL);
IAPECompress * __stdcall CreateIAPECompress(int * pErrorCode = NULL);
}
/*************************************************************************************************
Simple functions - see the SDK sample projects for usage examples
*************************************************************************************************/
extern "C"
{
// process whole files
DLLEXPORT int __stdcall CompressFile(const char * pInputFile, const char * pOutputFile, int nCompressionLevel = COMPRESSION_LEVEL_NORMAL, int * pPercentageDone = NULL, APE_PROGRESS_CALLBACK ProgressCallback = 0, int * pKillFlag = NULL);
DLLEXPORT int __stdcall DecompressFile(const char * pInputFilename, const char * pOutputFilename, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag);
DLLEXPORT int __stdcall ConvertFile(const char * pInputFilename, const char * pOutputFilename, int nCompressionLevel, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag);
DLLEXPORT int __stdcall VerifyFile(const char * pInputFilename, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag);
// helper functions
DLLEXPORT int __stdcall FillWaveFormatEx(WAVEFORMATEX * pWaveFormatEx, int nSampleRate = 44100, int nBitsPerSample = 16, int nChannels = 2);
DLLEXPORT int __stdcall FillWaveHeader(WAVE_HEADER * pWAVHeader, int nAudioBytes, WAVEFORMATEX * pWaveFormatEx, int nTerminatingBytes = 0);
}
#endif /* APE_MACLIB_H */