initial checkin

This commit is contained in:
chudov
2008-10-13 19:25:11 +00:00
parent 2e379c72e2
commit 36757fca7a
937 changed files with 184964 additions and 0 deletions

293
MAC_SDK/Shared/APETag.h Normal file
View File

@@ -0,0 +1,293 @@
#ifndef APE_APETAG_H
#define APE_APETAG_H
class CIO;
/*****************************************************************************************
APETag version history / supported formats
1.0 (1000) - Original APE tag spec. Fully supported by this code.
2.0 (2000) - Refined APE tag spec (better streaming support, UTF encoding). Fully supported by this code.
Notes:
- also supports reading of ID3v1.1 tags
- all saving done in the APE Tag format using CURRENT_APE_TAG_VERSION
*****************************************************************************************/
/*****************************************************************************************
APETag layout
1) Header - APE_TAG_FOOTER (optional) (32 bytes)
2) Fields (array):
Value Size (4 bytes)
Flags (4 bytes)
Field Name (? ANSI bytes -- requires NULL terminator -- in range of 0x20 (space) to 0x7E (tilde))
Value ([Value Size] bytes)
3) Footer - APE_TAG_FOOTER (32 bytes)
*****************************************************************************************/
/*****************************************************************************************
Notes
-When saving images, store the filename (no directory -- i.e. Cover.jpg) in UTF-8 followed
by a null terminator, followed by the image data.
*****************************************************************************************/
/*****************************************************************************************
The version of the APE tag
*****************************************************************************************/
#define CURRENT_APE_TAG_VERSION 2000
/*****************************************************************************************
"Standard" APE tag fields
*****************************************************************************************/
#define APE_TAG_FIELD_TITLE L"Title"
#define APE_TAG_FIELD_ARTIST L"Artist"
#define APE_TAG_FIELD_ALBUM L"Album"
#define APE_TAG_FIELD_COMMENT L"Comment"
#define APE_TAG_FIELD_YEAR L"Year"
#define APE_TAG_FIELD_TRACK L"Track"
#define APE_TAG_FIELD_GENRE L"Genre"
#define APE_TAG_FIELD_COVER_ART_FRONT L"Cover Art (front)"
#define APE_TAG_FIELD_NOTES L"Notes"
#define APE_TAG_FIELD_LYRICS L"Lyrics"
#define APE_TAG_FIELD_COPYRIGHT L"Copyright"
#define APE_TAG_FIELD_BUY_URL L"Buy URL"
#define APE_TAG_FIELD_ARTIST_URL L"Artist URL"
#define APE_TAG_FIELD_PUBLISHER_URL L"Publisher URL"
#define APE_TAG_FIELD_FILE_URL L"File URL"
#define APE_TAG_FIELD_COPYRIGHT_URL L"Copyright URL"
#define APE_TAG_FIELD_MJ_METADATA L"Media Jukebox Metadata"
#define APE_TAG_FIELD_TOOL_NAME L"Tool Name"
#define APE_TAG_FIELD_TOOL_VERSION L"Tool Version"
#define APE_TAG_FIELD_PEAK_LEVEL L"Peak Level"
#define APE_TAG_FIELD_REPLAY_GAIN_RADIO L"Replay Gain (radio)"
#define APE_TAG_FIELD_REPLAY_GAIN_ALBUM L"Replay Gain (album)"
#define APE_TAG_FIELD_COMPOSER L"Composer"
#define APE_TAG_FIELD_KEYWORDS L"Keywords"
/*****************************************************************************************
Standard APE tag field values
*****************************************************************************************/
#define APE_TAG_GENRE_UNDEFINED L"Undefined"
/*****************************************************************************************
ID3 v1.1 tag
*****************************************************************************************/
#define ID3_TAG_BYTES 128
struct ID3_TAG
{
char Header[3]; // should equal 'TAG'
char Title[30]; // title
char Artist[30]; // artist
char Album[30]; // album
char Year[4]; // year
char Comment[29]; // comment
unsigned char Track; // track
unsigned char Genre; // genre
};
/*****************************************************************************************
Footer (and header) flags
*****************************************************************************************/
#define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31)
#define APE_TAG_FLAG_CONTAINS_FOOTER (1 << 30)
#define APE_TAG_FLAG_IS_HEADER (1 << 29)
#define APE_TAG_FLAGS_DEFAULT (APE_TAG_FLAG_CONTAINS_FOOTER)
/*****************************************************************************************
Tag field flags
*****************************************************************************************/
#define TAG_FIELD_FLAG_READ_ONLY (1 << 0)
#define TAG_FIELD_FLAG_DATA_TYPE_MASK (6)
#define TAG_FIELD_FLAG_DATA_TYPE_TEXT_UTF8 (0 << 1)
#define TAG_FIELD_FLAG_DATA_TYPE_BINARY (1 << 1)
#define TAG_FIELD_FLAG_DATA_TYPE_EXTERNAL_INFO (2 << 1)
#define TAG_FIELD_FLAG_DATA_TYPE_RESERVED (3 << 1)
/*****************************************************************************************
The footer at the end of APE tagged files (can also optionally be at the front of the tag)
*****************************************************************************************/
#define APE_TAG_FOOTER_BYTES 32
class APE_TAG_FOOTER
{
protected:
char m_cID[8]; // should equal 'APETAGEX'
int m_nVersion; // equals CURRENT_APE_TAG_VERSION
int m_nSize; // the complete size of the tag, including this footer (excludes header)
int m_nFields; // the number of fields in the tag
int m_nFlags; // the tag flags
char m_cReserved[8]; // reserved for later use (must be zero)
public:
APE_TAG_FOOTER(int nFields = 0, int nFieldBytes = 0)
{
memcpy(m_cID, "APETAGEX", 8);
memset(m_cReserved, 0, 8);
m_nFields = nFields;
m_nFlags = APE_TAG_FLAGS_DEFAULT;
m_nSize = nFieldBytes + APE_TAG_FOOTER_BYTES;
m_nVersion = CURRENT_APE_TAG_VERSION;
}
int GetTotalTagBytes() { return m_nSize + (GetHasHeader() ? APE_TAG_FOOTER_BYTES : 0); }
int GetFieldBytes() { return m_nSize - APE_TAG_FOOTER_BYTES; }
int GetFieldsOffset() { return GetHasHeader() ? APE_TAG_FOOTER_BYTES : 0; }
int GetNumberFields() { return m_nFields; }
BOOL GetHasHeader() { return (m_nFlags & APE_TAG_FLAG_CONTAINS_HEADER) ? TRUE : FALSE; }
BOOL GetIsHeader() { return (m_nFlags & APE_TAG_FLAG_IS_HEADER) ? TRUE : FALSE; }
int GetVersion() { return m_nVersion; }
BOOL GetIsValid(BOOL bAllowHeader)
{
BOOL bValid = (strncmp(m_cID, "APETAGEX", 8) == 0) &&
(m_nVersion <= CURRENT_APE_TAG_VERSION) &&
(m_nFields <= 65536) &&
(GetFieldBytes() <= (1024 * 1024 * 16));
if (bValid && (bAllowHeader == FALSE) && GetIsHeader())
bValid = FALSE;
return bValid ? TRUE : FALSE;
}
};
/*****************************************************************************************
CAPETagField class (an APE tag is an array of these)
*****************************************************************************************/
class CAPETagField
{
public:
// create a tag field (use nFieldBytes = -1 for null-terminated strings)
CAPETagField(const str_utf16 * pFieldName, const void * pFieldValue, int nFieldBytes = -1, int nFlags = 0);
// destructor
~CAPETagField();
// gets the size of the entire field in bytes (name, value, and metadata)
int GetFieldSize();
// get the name of the field
const str_utf16 * GetFieldName();
// get the value of the field
const char * GetFieldValue();
// get the size of the value (in bytes)
int GetFieldValueSize();
// get any special flags
int GetFieldFlags();
// output the entire field to a buffer (GetFieldSize() bytes)
int SaveField(char * pBuffer);
// checks to see if the field is read-only
BOOL GetIsReadOnly() { return (m_nFieldFlags & TAG_FIELD_FLAG_READ_ONLY) ? TRUE : FALSE; }
BOOL GetIsUTF8Text() { return ((m_nFieldFlags & TAG_FIELD_FLAG_DATA_TYPE_MASK) == TAG_FIELD_FLAG_DATA_TYPE_TEXT_UTF8) ? TRUE : FALSE; }
// set helpers (use with EXTREME caution)
void SetFieldFlags(int nFlags) { m_nFieldFlags = nFlags; }
private:
CSmartPtr<str_utf16> m_spFieldNameUTF16;
CSmartPtr<char> m_spFieldValue;
int m_nFieldFlags;
int m_nFieldValueBytes;
};
/*****************************************************************************************
CAPETag class
*****************************************************************************************/
class CAPETag
{
public:
// create an APE tag
// bAnalyze determines whether it will analyze immediately or on the first request
// be careful with multiple threads / file pointer movement if you don't analyze immediately
CAPETag(CIO * pIO, BOOL bAnalyze = TRUE);
CAPETag(const str_utf16 * pFilename, BOOL bAnalyze = TRUE);
// destructor
~CAPETag();
// save the tag to the I/O source (bUseOldID3 forces it to save as an ID3v1.1 tag instead of an APE tag)
int Save(BOOL bUseOldID3 = FALSE);
// removes any tags from the file (bUpdate determines whether is should re-analyze after removing the tag)
int Remove(BOOL bUpdate = TRUE);
// sets the value of a field (use nFieldBytes = -1 for null terminated strings)
// note: using NULL or "" for a string type will remove the field
int SetFieldString(const str_utf16 * pFieldName, const str_utf16 * pFieldValue);
int SetFieldString(const str_utf16 * pFieldName, const char * pFieldValue, BOOL bAlreadyUTF8Encoded);
int SetFieldBinary(const str_utf16 * pFieldName, const void * pFieldValue, int nFieldBytes, int nFieldFlags);
// gets the value of a field (returns -1 and an empty buffer if the field doesn't exist)
int GetFieldBinary(const str_utf16 * pFieldName, void * pBuffer, int * pBufferBytes);
int GetFieldString(const str_utf16 * pFieldName, str_utf16 * pBuffer, int * pBufferCharacters);
int GetFieldString(const str_utf16 * pFieldName, str_ansi * pBuffer, int * pBufferCharacters, BOOL bUTF8Encode = FALSE);
// remove a specific field
int RemoveField(const str_utf16 * pFieldName);
int RemoveField(int nIndex);
// clear all the fields
int ClearFields();
// get the total tag bytes in the file from the last analyze
// need to call Save() then Analyze() to update any changes
int GetTagBytes();
// fills in an ID3_TAG using the current fields (useful for quickly converting the tag)
int CreateID3Tag(ID3_TAG * pID3Tag);
// see whether the file has an ID3 or APE tag
BOOL GetHasID3Tag() { if (m_bAnalyzed == FALSE) { Analyze(); } return m_bHasID3Tag; }
BOOL GetHasAPETag() { if (m_bAnalyzed == FALSE) { Analyze(); } return m_bHasAPETag; }
int GetAPETagVersion() { return GetHasAPETag() ? m_nAPETagVersion : -1; }
// gets a desired tag field (returns NULL if not found)
// again, be careful, because this a pointer to the actual field in this class
CAPETagField * GetTagField(const str_utf16 * pFieldName);
CAPETagField * GetTagField(int nIndex);
// options
void SetIgnoreReadOnly(BOOL bIgnoreReadOnly) { m_bIgnoreReadOnly = bIgnoreReadOnly; }
private:
// private functions
int Analyze();
int GetTagFieldIndex(const str_utf16 * pFieldName);
int WriteBufferToEndOfIO(void * pBuffer, int nBytes);
int LoadField(const char * pBuffer, int nMaximumBytes, int * pBytes);
int SortFields();
static int CompareFields(const void * pA, const void * pB);
// helper set / get field functions
int SetFieldID3String(const str_utf16 * pFieldName, const char * pFieldValue, int nBytes);
int GetFieldID3String(const str_utf16 * pFieldName, char * pBuffer, int nBytes);
// private data
CSmartPtr<CIO> m_spIO;
BOOL m_bAnalyzed;
int m_nTagBytes;
int m_nFields;
CAPETagField * m_aryFields[256];
BOOL m_bHasAPETag;
int m_nAPETagVersion;
BOOL m_bHasID3Tag;
BOOL m_bIgnoreReadOnly;
};
#endif // #ifndef APE_APETAG_H

235
MAC_SDK/Shared/All.h Normal file
View File

@@ -0,0 +1,235 @@
#ifndef APE_ALL_H
#define APE_ALL_H
/*****************************************************************************************
Cross platform building switch
*****************************************************************************************/
//#define BUILD_CROSS_PLATFORM
/*****************************************************************************************
Unicode
*****************************************************************************************/
#ifdef _UNICODE
#else
#endif // #ifdef _UNICODE
/*****************************************************************************************
Global includes
*****************************************************************************************/
#ifndef BUILD_CROSS_PLATFORM
// #include <windows.h>
#endif
#ifdef _WIN32
// #include <mmsystem.h>
#include <tchar.h>
#else
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "NoWindows.h"
#endif
#include <stdlib.h>
#include <memory.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "SmartPtr.h"
/*****************************************************************************************
Global compiler settings (useful for porting)
*****************************************************************************************/
#ifndef BUILD_CROSS_PLATFORM
#define ENABLE_ASSEMBLY
#endif
#define BACKWARDS_COMPATIBILITY
#define ENABLE_COMPRESSION_MODE_FAST
#define ENABLE_COMPRESSION_MODE_NORMAL
#define ENABLE_COMPRESSION_MODE_HIGH
#define ENABLE_COMPRESSION_MODE_EXTRA_HIGH
#ifdef _WIN32
typedef unsigned __int32 uint32;
typedef __int32 int32;
typedef unsigned __int16 uint16;
typedef __int16 int16;
typedef unsigned __int8 uint8;
typedef __int8 int8;
typedef char str_ansi;
typedef unsigned char str_utf8;
typedef wchar_t str_utf16;
#define IO_USE_WIN_FILE_IO
#define IO_HEADER_FILE "WinFileIO.h"
#define IO_CLASS_NAME CWinFileIO
#define DLLEXPORT __declspec(dllexport)
#define SLEEP(MILLISECONDS) ::Sleep(MILLISECONDS)
#define MESSAGEBOX(PARENT, TEXT, CAPTION, TYPE) ::MessageBox(PARENT, TEXT, CAPTION, TYPE)
#define PUMP_MESSAGE_LOOP { MSG Msg; while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE) != 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } }
#define ODS OutputDebugString
#define TICK_COUNT_TYPE unsigned long
#define TICK_COUNT_READ(VARIABLE) VARIABLE = GetTickCount()
#define TICK_COUNT_FREQ 1000
#else
#define IO_USE_STD_LIB_FILE_IO
#define IO_HEADER_FILE "StdLibFileIO.h"
#define IO_CLASS_NAME CStdLibFileIO
#define DLLEXPORT
#define SLEEP(MILLISECONDS) { struct timespec t; t.tv_sec = (MILLISECONDS) / 1000; t.tv_nsec = (MILLISECONDS) % 1000 * 1000000; nanosleep(&t, NULL); }
#define MESSAGEBOX(PARENT, TEXT, CAPTION, TYPE)
#define PUMP_MESSAGE_LOOP
#define ODS printf
#define TICK_COUNT_TYPE unsigned long long
#define TICK_COUNT_READ(VARIABLE) { struct timeval t; gettimeofday(&t, NULL); VARIABLE = t.tv_sec * 1000000LLU + t.tv_usec; }
#define TICK_COUNT_FREQ 1000000
#endif
/*****************************************************************************************
Global defines
*****************************************************************************************/
#define MAC_VERSION_NUMBER 3990
#define MAC_VERSION_STRING _T("3.99")
#define MAC_NAME _T("Monkey's Audio 3.99")
#define PLUGIN_NAME "Monkey's Audio Player v3.99"
#define MJ_PLUGIN_NAME _T("APE Plugin (v3.99)")
#define CONSOLE_NAME "--- Monkey's Audio Console Front End (v 3.99) (c) Matthew T. Ashland ---\n"
#define PLUGIN_ABOUT _T("Monkey's Audio Player v3.99\nCopyrighted (c) 2000-2004 by Matthew T. Ashland")
#define MAC_DLL_INTERFACE_VERSION_NUMBER 1000
/*****************************************************************************************
Byte order
*****************************************************************************************/
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
/*****************************************************************************************
Macros
*****************************************************************************************/
#define MB(TEST) MESSAGEBOX(NULL, TEST, _T("Information"), MB_OK);
#define MBN(NUMBER) { TCHAR cNumber[16]; _stprintf(cNumber, _T("%d"), NUMBER); MESSAGEBOX(NULL, cNumber, _T("Information"), MB_OK); }
#define SAFE_DELETE(POINTER) if (POINTER) { delete POINTER; POINTER = NULL; }
#define SAFE_ARRAY_DELETE(POINTER) if (POINTER) { delete [] POINTER; POINTER = NULL; }
#define SAFE_VOID_CLASS_DELETE(POINTER, Class) { Class *pClass = (Class *) POINTER; if (pClass) { delete pClass; POINTER = NULL; } }
#define SAFE_FILE_CLOSE(HANDLE) if (HANDLE != INVALID_HANDLE_VALUE) { CloseHandle(HANDLE); HANDLE = INVALID_HANDLE_VALUE; }
#define ODN(NUMBER) { TCHAR cNumber[16]; _stprintf(cNumber, _T("%d\n"), int(NUMBER)); ODS(cNumber); }
#define CATCH_ERRORS(CODE) try { CODE } catch(...) { }
#define RETURN_ON_ERROR(FUNCTION) { int nRetVal = FUNCTION; if (nRetVal != 0) { return nRetVal; } }
#define RETURN_VALUE_ON_ERROR(FUNCTION, VALUE) { int nRetVal = FUNCTION; if (nRetVal != 0) { return VALUE; } }
#define RETURN_ON_EXCEPTION(CODE, VALUE) { try { CODE } catch(...) { return VALUE; } }
#define THROW_ON_ERROR(CODE) { int nRetVal = CODE; if (nRetVal != 0) throw(nRetVal); }
#define EXPAND_1_TIMES(CODE) CODE
#define EXPAND_2_TIMES(CODE) CODE CODE
#define EXPAND_3_TIMES(CODE) CODE CODE CODE
#define EXPAND_4_TIMES(CODE) CODE CODE CODE CODE
#define EXPAND_5_TIMES(CODE) CODE CODE CODE CODE CODE
#define EXPAND_6_TIMES(CODE) CODE CODE CODE CODE CODE CODE
#define EXPAND_7_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_8_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_9_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_12_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_14_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_15_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_16_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_30_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_31_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_32_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_64_TIMES(CODE) CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE CODE
#define EXPAND_N_TIMES(NUMBER, CODE) EXPAND_##NUMBER##_TIMES(CODE)
#define UNROLL_4_TIMES(MACRO) MACRO(0) MACRO(1) MACRO(2) MACRO(3)
#define UNROLL_8_TIMES(MACRO) MACRO(0) MACRO(1) MACRO(2) MACRO(3) MACRO(4) MACRO(5) MACRO(6) MACRO(7)
#define UNROLL_15_TIMES(MACRO) MACRO(0) MACRO(1) MACRO(2) MACRO(3) MACRO(4) MACRO(5) MACRO(6) MACRO(7) MACRO(8) MACRO(9) MACRO(10) MACRO(11) MACRO(12) MACRO(13) MACRO(14)
#define UNROLL_16_TIMES(MACRO) MACRO(0) MACRO(1) MACRO(2) MACRO(3) MACRO(4) MACRO(5) MACRO(6) MACRO(7) MACRO(8) MACRO(9) MACRO(10) MACRO(11) MACRO(12) MACRO(13) MACRO(14) MACRO(15)
#define UNROLL_64_TIMES(MACRO) MACRO(0) MACRO(1) MACRO(2) MACRO(3) MACRO(4) MACRO(5) MACRO(6) MACRO(7) MACRO(8) MACRO(9) MACRO(10) MACRO(11) MACRO(12) MACRO(13) MACRO(14) MACRO(15) MACRO(16) MACRO(17) MACRO(18) MACRO(19) MACRO(20) MACRO(21) MACRO(22) MACRO(23) MACRO(24) MACRO(25) MACRO(26) MACRO(27) MACRO(28) MACRO(29) MACRO(30) MACRO(31) MACRO(32) MACRO(33) MACRO(34) MACRO(35) MACRO(36) MACRO(37) MACRO(38) MACRO(39) MACRO(40) MACRO(41) MACRO(42) MACRO(43) MACRO(44) MACRO(45) MACRO(46) MACRO(47) MACRO(48) MACRO(49) MACRO(50) MACRO(51) MACRO(52) MACRO(53) MACRO(54) MACRO(55) MACRO(56) MACRO(57) MACRO(58) MACRO(59) MACRO(60) MACRO(61) MACRO(62) MACRO(63)
#define UNROLL_128_TIMES(MACRO) MACRO(0) MACRO(1) MACRO(2) MACRO(3) MACRO(4) MACRO(5) MACRO(6) MACRO(7) MACRO(8) MACRO(9) MACRO(10) MACRO(11) MACRO(12) MACRO(13) MACRO(14) MACRO(15) MACRO(16) MACRO(17) MACRO(18) MACRO(19) MACRO(20) MACRO(21) MACRO(22) MACRO(23) MACRO(24) MACRO(25) MACRO(26) MACRO(27) MACRO(28) MACRO(29) MACRO(30) MACRO(31) MACRO(32) MACRO(33) MACRO(34) MACRO(35) MACRO(36) MACRO(37) MACRO(38) MACRO(39) MACRO(40) MACRO(41) MACRO(42) MACRO(43) MACRO(44) MACRO(45) MACRO(46) MACRO(47) MACRO(48) MACRO(49) MACRO(50) MACRO(51) MACRO(52) MACRO(53) MACRO(54) MACRO(55) MACRO(56) MACRO(57) MACRO(58) MACRO(59) MACRO(60) MACRO(61) MACRO(62) MACRO(63) MACRO(64) MACRO(65) MACRO(66) MACRO(67) MACRO(68) MACRO(69) MACRO(70) MACRO(71) MACRO(72) MACRO(73) MACRO(74) MACRO(75) MACRO(76) MACRO(77) MACRO(78) MACRO(79) MACRO(80) MACRO(81) MACRO(82) MACRO(83) MACRO(84) MACRO(85) MACRO(86) MACRO(87) MACRO(88) MACRO(89) MACRO(90) MACRO(91) MACRO(92) MACRO(93) MACRO(94) MACRO(95) MACRO(96) MACRO(97) MACRO(98) MACRO(99) MACRO(100) MACRO(101) MACRO(102) MACRO(103) MACRO(104) MACRO(105) MACRO(106) MACRO(107) MACRO(108) MACRO(109) MACRO(110) MACRO(111) MACRO(112) MACRO(113) MACRO(114) MACRO(115) MACRO(116) MACRO(117) MACRO(118) MACRO(119) MACRO(120) MACRO(121) MACRO(122) MACRO(123) MACRO(124) MACRO(125) MACRO(126) MACRO(127)
#define UNROLL_256_TIMES(MACRO) MACRO(0) MACRO(1) MACRO(2) MACRO(3) MACRO(4) MACRO(5) MACRO(6) MACRO(7) MACRO(8) MACRO(9) MACRO(10) MACRO(11) MACRO(12) MACRO(13) MACRO(14) MACRO(15) MACRO(16) MACRO(17) MACRO(18) MACRO(19) MACRO(20) MACRO(21) MACRO(22) MACRO(23) MACRO(24) MACRO(25) MACRO(26) MACRO(27) MACRO(28) MACRO(29) MACRO(30) MACRO(31) MACRO(32) MACRO(33) MACRO(34) MACRO(35) MACRO(36) MACRO(37) MACRO(38) MACRO(39) MACRO(40) MACRO(41) MACRO(42) MACRO(43) MACRO(44) MACRO(45) MACRO(46) MACRO(47) MACRO(48) MACRO(49) MACRO(50) MACRO(51) MACRO(52) MACRO(53) MACRO(54) MACRO(55) MACRO(56) MACRO(57) MACRO(58) MACRO(59) MACRO(60) MACRO(61) MACRO(62) MACRO(63) MACRO(64) MACRO(65) MACRO(66) MACRO(67) MACRO(68) MACRO(69) MACRO(70) MACRO(71) MACRO(72) MACRO(73) MACRO(74) MACRO(75) MACRO(76) MACRO(77) MACRO(78) MACRO(79) MACRO(80) MACRO(81) MACRO(82) MACRO(83) MACRO(84) MACRO(85) MACRO(86) MACRO(87) MACRO(88) MACRO(89) MACRO(90) MACRO(91) MACRO(92) MACRO(93) MACRO(94) MACRO(95) MACRO(96) MACRO(97) MACRO(98) MACRO(99) MACRO(100) MACRO(101) MACRO(102) MACRO(103) MACRO(104) MACRO(105) MACRO(106) MACRO(107) MACRO(108) MACRO(109) MACRO(110) MACRO(111) MACRO(112) MACRO(113) MACRO(114) MACRO(115) MACRO(116) MACRO(117) MACRO(118) MACRO(119) MACRO(120) MACRO(121) MACRO(122) MACRO(123) MACRO(124) MACRO(125) MACRO(126) MACRO(127) \
MACRO(128) MACRO(129) MACRO(130) MACRO(131) MACRO(132) MACRO(133) MACRO(134) MACRO(135) MACRO(136) MACRO(137) MACRO(138) MACRO(139) MACRO(140) MACRO(141) MACRO(142) MACRO(143) MACRO(144) MACRO(145) MACRO(146) MACRO(147) MACRO(148) MACRO(149) MACRO(150) MACRO(151) MACRO(152) MACRO(153) MACRO(154) MACRO(155) MACRO(156) MACRO(157) MACRO(158) MACRO(159) MACRO(160) MACRO(161) MACRO(162) MACRO(163) MACRO(164) MACRO(165) MACRO(166) MACRO(167) MACRO(168) MACRO(169) MACRO(170) MACRO(171) MACRO(172) MACRO(173) MACRO(174) MACRO(175) MACRO(176) MACRO(177) MACRO(178) MACRO(179) MACRO(180) MACRO(181) MACRO(182) MACRO(183) MACRO(184) MACRO(185) MACRO(186) MACRO(187) MACRO(188) MACRO(189) MACRO(190) MACRO(191) MACRO(192) MACRO(193) MACRO(194) MACRO(195) MACRO(196) MACRO(197) MACRO(198) MACRO(199) MACRO(200) MACRO(201) MACRO(202) MACRO(203) MACRO(204) MACRO(205) MACRO(206) MACRO(207) MACRO(208) MACRO(209) MACRO(210) MACRO(211) MACRO(212) MACRO(213) MACRO(214) MACRO(215) MACRO(216) MACRO(217) MACRO(218) MACRO(219) MACRO(220) MACRO(221) MACRO(222) MACRO(223) MACRO(224) MACRO(225) MACRO(226) MACRO(227) MACRO(228) MACRO(229) MACRO(230) MACRO(231) MACRO(232) MACRO(233) MACRO(234) MACRO(235) MACRO(236) MACRO(237) MACRO(238) MACRO(239) MACRO(240) MACRO(241) MACRO(242) MACRO(243) MACRO(244) MACRO(245) MACRO(246) MACRO(247) MACRO(248) MACRO(249) MACRO(250) MACRO(251) MACRO(252) MACRO(253) MACRO(254) MACRO(255)
/*****************************************************************************************
Error Codes
*****************************************************************************************/
// success
#ifndef ERROR_SUCCESS
#define ERROR_SUCCESS 0
#endif
// file and i/o errors (1000's)
#define ERROR_IO_READ 1000
#define ERROR_IO_WRITE 1001
#define ERROR_INVALID_INPUT_FILE 1002
#define ERROR_INVALID_OUTPUT_FILE 1003
#define ERROR_INPUT_FILE_TOO_LARGE 1004
#define ERROR_INPUT_FILE_UNSUPPORTED_BIT_DEPTH 1005
#define ERROR_INPUT_FILE_UNSUPPORTED_SAMPLE_RATE 1006
#define ERROR_INPUT_FILE_UNSUPPORTED_CHANNEL_COUNT 1007
#define ERROR_INPUT_FILE_TOO_SMALL 1008
#define ERROR_INVALID_CHECKSUM 1009
#define ERROR_DECOMPRESSING_FRAME 1010
#define ERROR_INITIALIZING_UNMAC 1011
#define ERROR_INVALID_FUNCTION_PARAMETER 1012
#define ERROR_UNSUPPORTED_FILE_TYPE 1013
#define ERROR_UPSUPPORTED_FILE_VERSION 1014
// memory errors (2000's)
#define ERROR_INSUFFICIENT_MEMORY 2000
// dll errors (3000's)
#define ERROR_LOADINGAPE_DLL 3000
#define ERROR_LOADINGAPE_INFO_DLL 3001
#define ERROR_LOADING_UNMAC_DLL 3002
// general and misc errors
#define ERROR_USER_STOPPED_PROCESSING 4000
#define ERROR_SKIPPED 4001
// programmer errors
#define ERROR_BAD_PARAMETER 5000
// IAPECompress errors
#define ERROR_APE_COMPRESS_TOO_MUCH_DATA 6000
// unknown error
#define ERROR_UNDEFINED -1
#define ERROR_EXPLANATION \
{ ERROR_IO_READ , "I/O read error" }, \
{ ERROR_IO_WRITE , "I/O write error" }, \
{ ERROR_INVALID_INPUT_FILE , "invalid input file" }, \
{ ERROR_INVALID_OUTPUT_FILE , "invalid output file" }, \
{ ERROR_INPUT_FILE_TOO_LARGE , "input file file too large" }, \
{ ERROR_INPUT_FILE_UNSUPPORTED_BIT_DEPTH , "input file unsupported bit depth" }, \
{ ERROR_INPUT_FILE_UNSUPPORTED_SAMPLE_RATE , "input file unsupported sample rate" }, \
{ ERROR_INPUT_FILE_UNSUPPORTED_CHANNEL_COUNT , "input file unsupported channel count" }, \
{ ERROR_INPUT_FILE_TOO_SMALL , "input file too small" }, \
{ ERROR_INVALID_CHECKSUM , "invalid checksum" }, \
{ ERROR_DECOMPRESSING_FRAME , "decompressing frame" }, \
{ ERROR_INITIALIZING_UNMAC , "initializing unmac" }, \
{ ERROR_INVALID_FUNCTION_PARAMETER , "invalid function parameter" }, \
{ ERROR_UNSUPPORTED_FILE_TYPE , "unsupported file type" }, \
{ ERROR_INSUFFICIENT_MEMORY , "insufficient memory" }, \
{ ERROR_LOADINGAPE_DLL , "loading MAC.dll" }, \
{ ERROR_LOADINGAPE_INFO_DLL , "loading MACinfo.dll" }, \
{ ERROR_LOADING_UNMAC_DLL , "loading UnMAC.dll" }, \
{ ERROR_USER_STOPPED_PROCESSING , "user stopped processing" }, \
{ ERROR_SKIPPED , "skipped" }, \
{ ERROR_BAD_PARAMETER , "bad parameter" }, \
{ ERROR_APE_COMPRESS_TOO_MUCH_DATA , "APE compress too much data" }, \
{ ERROR_UNDEFINED , "undefined" }, \
#endif // #ifndef APE_ALL_H

49
MAC_SDK/Shared/IO.h Normal file
View File

@@ -0,0 +1,49 @@
#ifndef APE_IO_H
#define APE_IO_H
#ifndef FILE_BEGIN
#define FILE_BEGIN 0
#endif
#ifndef FILE_CURRENT
#define FILE_CURRENT 1
#endif
#ifndef FILE_END
#define FILE_END 2
#endif
class CIO
{
public:
//construction / destruction
CIO() { }
virtual ~CIO() { };
// open / close
virtual int Open(const wchar_t * pName) = 0;
virtual int Close() = 0;
// read / write
virtual int Read(void * pBuffer, unsigned int nBytesToRead, unsigned int * pBytesRead) = 0;
virtual int Write(const void * pBuffer, unsigned int nBytesToWrite, unsigned int * pBytesWritten) = 0;
// seek
virtual int Seek(int nDistance, unsigned int nMoveMode) = 0;
// creation / destruction
virtual int Create(const wchar_t * pName) = 0;
virtual int Delete() = 0;
// other functions
virtual int SetEOF() = 0;
// attributes
virtual int GetPosition() = 0;
virtual int GetSize() = 0;
virtual int GetName(wchar_t * pBuffer) = 0;
};
#endif // #ifndef APE_IO_H

99
MAC_SDK/Shared/MACDll.h Normal file
View File

@@ -0,0 +1,99 @@
/*****************************************************************************************
Monkey's Audio MACDll.h (include for using MACDll.dll in your projects)
Copyright (C) 2000-2004 by Matthew T. Ashland All Rights Reserved.
Overview:
Basically all this dll does is wrap MACLib.lib, so browse through MACLib.h for documentation
on how to use the interfaces.
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, matt @ monkeysaudio.com
*****************************************************************************************/
#ifndef APE_MACDLL_H
#define APE_MACDLL_H
/*****************************************************************************************
Includes
*****************************************************************************************/
#include "All.h"
#include "MACLib.h"
/*****************************************************************************************
Defines (implemented elsewhere)
*****************************************************************************************/
struct ID3_TAG;
/*****************************************************************************************
Helper functions
*****************************************************************************************/
extern "C"
{
__declspec( dllexport ) int __stdcall GetVersionNumber();
__declspec( dllexport ) int __stdcall GetInterfaceCompatibility(int nVersion, BOOL bDisplayWarningsOnFailure = TRUE, HWND hwndParent = NULL);
__declspec( dllexport ) int __stdcall ShowFileInfoDialog(const str_ansi * pFilename, HWND hwndWindow);
__declspec( dllexport ) int __stdcall TagFileSimple(const str_ansi * pFilename, const char * pArtist, const char * pAlbum, const char * pTitle, const char * pComment, const char * pGenre, const char * pYear, const char * pTrack, BOOL bClearFirst, BOOL bUseOldID3);
__declspec( dllexport ) int __stdcall GetID3Tag(const str_ansi * pFilename, ID3_TAG * pID3Tag);
__declspec( dllexport ) int __stdcall RemoveTag(const str_ansi * pFilename);
}
typedef int (__stdcall * proc_GetVersionNumber)();
typedef int (__stdcall * proc_GetInterfaceCompatibility)(int, BOOL, HWND);
/*****************************************************************************************
IAPECompress wrapper(s)
*****************************************************************************************/
typedef void * APE_COMPRESS_HANDLE;
typedef APE_COMPRESS_HANDLE (__stdcall * proc_APECompress_Create)(int *);
typedef void (__stdcall * proc_APECompress_Destroy)(APE_COMPRESS_HANDLE);
typedef int (__stdcall * proc_APECompress_Start)(APE_COMPRESS_HANDLE, const char *, const WAVEFORMATEX *, int, int, const void *, int);
typedef int (__stdcall * proc_APECompress_StartW)(APE_COMPRESS_HANDLE, const char *, const WAVEFORMATEX *, int, int, const void *, int);
typedef int (__stdcall * proc_APECompress_AddData)(APE_COMPRESS_HANDLE, unsigned char *, int);
typedef int (__stdcall * proc_APECompress_GetBufferBytesAvailable)(APE_COMPRESS_HANDLE);
typedef unsigned char * (__stdcall * proc_APECompress_LockBuffer)(APE_COMPRESS_HANDLE, int *);
typedef int (__stdcall * proc_APECompress_UnlockBuffer)(APE_COMPRESS_HANDLE, int, BOOL);
typedef int (__stdcall * proc_APECompress_Finish)(APE_COMPRESS_HANDLE, unsigned char *, int, int);
typedef int (__stdcall * proc_APECompress_Kill)(APE_COMPRESS_HANDLE);
extern "C"
{
__declspec( dllexport ) APE_COMPRESS_HANDLE __stdcall c_APECompress_Create(int * pErrorCode = NULL);
__declspec( dllexport ) void __stdcall c_APECompress_Destroy(APE_COMPRESS_HANDLE hAPECompress);
__declspec( dllexport ) int __stdcall c_APECompress_Start(APE_COMPRESS_HANDLE hAPECompress, 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);
__declspec( dllexport ) int __stdcall c_APECompress_StartW(APE_COMPRESS_HANDLE hAPECompress, const str_utf16 * 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);
__declspec( dllexport ) int __stdcall c_APECompress_AddData(APE_COMPRESS_HANDLE hAPECompress, unsigned char * pData, int nBytes);
__declspec( dllexport ) int __stdcall c_APECompress_GetBufferBytesAvailable(APE_COMPRESS_HANDLE hAPECompress);
__declspec( dllexport ) unsigned char * __stdcall c_APECompress_LockBuffer(APE_COMPRESS_HANDLE hAPECompress, int * pBytesAvailable);
__declspec( dllexport ) int __stdcall c_APECompress_UnlockBuffer(APE_COMPRESS_HANDLE hAPECompress, int nBytesAdded, BOOL bProcess = TRUE);
__declspec( dllexport ) int __stdcall c_APECompress_Finish(APE_COMPRESS_HANDLE hAPECompress, unsigned char * pTerminatingData, int nTerminatingBytes, int nWAVTerminatingBytes);
__declspec( dllexport ) int __stdcall c_APECompress_Kill(APE_COMPRESS_HANDLE hAPECompress);
}
/*****************************************************************************************
IAPEDecompress wrapper(s)
*****************************************************************************************/
typedef void * APE_DECOMPRESS_HANDLE;
typedef APE_DECOMPRESS_HANDLE (__stdcall * proc_APEDecompress_Create)(const char *, int *);
typedef APE_DECOMPRESS_HANDLE (__stdcall * proc_APEDecompress_CreateW)(const char *, int *);
typedef void (__stdcall * proc_APEDecompress_Destroy)(APE_DECOMPRESS_HANDLE);
typedef int (__stdcall * proc_APEDecompress_GetData)(APE_DECOMPRESS_HANDLE, char *, int, int *);
typedef int (__stdcall * proc_APEDecompress_Seek)(APE_DECOMPRESS_HANDLE, int);
typedef int (__stdcall * proc_APEDecompress_GetInfo)(APE_DECOMPRESS_HANDLE, APE_DECOMPRESS_FIELDS, int, int);
extern "C"
{
__declspec( dllexport ) APE_DECOMPRESS_HANDLE __stdcall c_APEDecompress_Create(const str_ansi * pFilename, int * pErrorCode = NULL);
__declspec( dllexport ) APE_DECOMPRESS_HANDLE __stdcall c_APEDecompress_CreateW(const str_utf16 * pFilename, int * pErrorCode = NULL);
__declspec( dllexport ) void __stdcall c_APEDecompress_Destroy(APE_DECOMPRESS_HANDLE hAPEDecompress);
__declspec( dllexport ) int __stdcall c_APEDecompress_GetData(APE_DECOMPRESS_HANDLE hAPEDecompress, char * pBuffer, int nBlocks, int * pBlocksRetrieved);
__declspec( dllexport ) int __stdcall c_APEDecompress_Seek(APE_DECOMPRESS_HANDLE hAPEDecompress, int nBlockOffset);
__declspec( dllexport ) int __stdcall c_APEDecompress_GetInfo(APE_DECOMPRESS_HANDLE hAPEDecompress, APE_DECOMPRESS_FIELDS Field, int nParam1 = 0, int nParam2 = 0);
}
#endif // #ifndef APE_MACDLL_H

450
MAC_SDK/Shared/MACLib.h Normal file
View File

@@ -0,0 +1,450 @@
/*****************************************************************************************
Monkey's Audio MACLib.h (include for using MACLib.lib in your projects)
Copyright (C) 2000-2003 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 per 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, matt @ monkeysaudio.com
*****************************************************************************************/
#ifndef APE_MACLIB_H
#define APE_MACLIB_H
/*************************************************************************************************
APE File Format Overview: (pieces in order -- only valid for the latest version APE files)
JUNK - any amount of "junk" before the APE_DESCRIPTOR (so people that put ID3v2 tags on the files aren't hosed)
APE_DESCRIPTOR - defines the sizes (and offsets) of all the pieces, as well as the MD5 checksum
APE_HEADER - describes all of the necessary information about the APE file
SEEK TABLE - the table that represents seek offsets [optional]
HEADER DATA - the pre-audio data from the original file [optional]
APE FRAMES - the actual compressed audio (broken into frames for seekability)
TERMINATING DATA - the post-audio data from the original file [optional]
TAG - describes all the properties of the file [optional]
Notes:
Junk:
This block may not be supported in the future, so don't write any software that adds meta data
before the APE_DESCRIPTOR. Please use the APE Tag for any meta data.
Seek Table:
A 32-bit unsigned integer array of offsets from the header to the frame data. May become "delta"
values someday to better suit huge files.
MD5 Hash:
Since the header is the last part written to an APE file, you must calculate the MD5 checksum out of order.
So, you first calculate from the tail of the seek table to the end of the terminating data.
Then, go back and do from the end of the descriptor to the tail of the seek table.
You may wish to just cache the header data when starting and run it last, so you don't
need to seek back in the I/O.
*************************************************************************************************/
/*****************************************************************************************
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 5000
#define MAC_FORMAT_FLAG_8_BIT 1 // is 8-bit [OBSOLETE]
#define MAC_FORMAT_FLAG_CRC 2 // uses the new CRC32 error detection [OBSOLETE]
#define MAC_FORMAT_FLAG_HAS_PEAK_LEVEL 4 // uint32 nPeakLevel after the header [OBSOLETE]
#define MAC_FORMAT_FLAG_24_BIT 8 // is 24-bit [OBSOLETE]
#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_DESCRIPTOR structure (file header that describes lengths, offsets, etc.)
*****************************************************************************************/
struct APE_DESCRIPTOR
{
char cID[4]; // should equal 'MAC '
uint16 nVersion; // version number * 1000 (3.81 = 3810)
uint32 nDescriptorBytes; // the number of descriptor bytes (allows later expansion of this header)
uint32 nHeaderBytes; // the number of header APE_HEADER bytes
uint32 nSeekTableBytes; // the number of bytes of the seek table
uint32 nHeaderDataBytes; // the number of header data bytes (from original file)
uint32 nAPEFrameDataBytes; // the number of bytes of APE frame data
uint32 nAPEFrameDataBytesHigh; // the high order number of APE frame data bytes
uint32 nTerminatingDataBytes; // the terminating data of the file (not including tag data)
uint8 cFileMD5[16]; // the MD5 hash of the file (see notes for usage... it's a littly tricky)
};
/*****************************************************************************************
APE_HEADER structure (describes the format, duration, etc. of the APE file)
*****************************************************************************************/
struct APE_HEADER
{
uint16 nCompressionLevel; // the compression level (see defines I.E. COMPRESSION_LEVEL_FAST)
uint16 nFormatFlags; // any format flags (for future use)
uint32 nBlocksPerFrame; // the number of audio blocks in one frame
uint32 nFinalFrameBlocks; // the number of audio blocks in the final frame
uint32 nTotalFrames; // the total number of frames
uint16 nBitsPerSample; // the bits per sample (typically 16)
uint16 nChannels; // the number of channels (1 or 2)
uint32 nSampleRate; // the sample rate (typically 44100)
};
/*************************************************************************************************
Classes (fully defined elsewhere)
*************************************************************************************************/
class CIO;
class CInputSource;
class CAPEInfo;
/*************************************************************************************************
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 (obsolete) (-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]
APE_INTERNAL_INFO = 3000, // for internal use -- don't use (returns APE_FILE_INFO *) [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 str_utf16 * 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 void * 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 str_utf16 * pOutputFilename, const WAVEFORMATEX * pwfeInput,
int nMaxAudioBytes = MAX_AUDIO_BYTES_UNKNOWN, int nCompressionLevel = COMPRESSION_LEVEL_NORMAL,
const void * 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 void * 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 str_utf16 * pFilename, int * pErrorCode = NULL);
IAPEDecompress * __stdcall CreateIAPEDecompressEx(CIO * pIO, int * pErrorCode = NULL);
IAPEDecompress * __stdcall CreateIAPEDecompressEx2(CAPEInfo * pAPEInfo, int nStartBlock = -1, int nFinishBlock = -1, 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 str_ansi * pInputFilename, const str_ansi * pOutputFilename, int nCompressionLevel = COMPRESSION_LEVEL_NORMAL, int * pPercentageDone = NULL, APE_PROGRESS_CALLBACK ProgressCallback = 0, int * pKillFlag = NULL);
DLLEXPORT int __stdcall DecompressFile(const str_ansi * pInputFilename, const str_ansi * pOutputFilename, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag);
DLLEXPORT int __stdcall ConvertFile(const str_ansi * pInputFilename, const str_ansi * pOutputFilename, int nCompressionLevel, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag);
DLLEXPORT int __stdcall VerifyFile(const str_ansi * pInputFilename, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag);
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);
DLLEXPORT int __stdcall DecompressFileW(const str_utf16 * pInputFilename, const str_utf16 * pOutputFilename, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag);
DLLEXPORT int __stdcall ConvertFileW(const str_utf16 * pInputFilename, const str_utf16 * pOutputFilename, int nCompressionLevel, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag);
DLLEXPORT int __stdcall VerifyFileW(const str_utf16 * pInputFilename, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag, BOOL bQuickVerifyIfPossible = FALSE);
// 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 // #ifndef APE_MACLIB_H

89
MAC_SDK/Shared/SmartPtr.h Normal file
View File

@@ -0,0 +1,89 @@
#ifndef APE_SMARTPTR_H
#define APE_SMARTPTR_H
// disable the operator -> on UDT warning
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4284)
#endif
/*************************************************************************************************
CSmartPtr - a simple smart pointer class that can automatically initialize and free memory
note: (doesn't do garbage collection / reference counting because of the many pitfalls)
*************************************************************************************************/
template <class TYPE> class CSmartPtr
{
public:
TYPE * m_pObject;
BOOL m_bArray;
BOOL m_bDelete;
CSmartPtr()
{
m_bDelete = TRUE;
m_pObject = NULL;
}
CSmartPtr(TYPE * a_pObject, BOOL a_bArray = FALSE, BOOL a_bDelete = TRUE)
{
m_bDelete = TRUE;
m_pObject = NULL;
Assign(a_pObject, a_bArray, a_bDelete);
}
~CSmartPtr()
{
Delete();
}
void Assign(TYPE * a_pObject, BOOL a_bArray = FALSE, BOOL a_bDelete = TRUE)
{
Delete();
m_bDelete = a_bDelete;
m_bArray = a_bArray;
m_pObject = a_pObject;
}
void Delete()
{
if (m_bDelete && m_pObject)
{
if (m_bArray)
delete [] m_pObject;
else
delete m_pObject;
m_pObject = NULL;
}
}
void SetDelete(const BOOL a_bDelete)
{
m_bDelete = a_bDelete;
}
__inline TYPE * GetPtr() const
{
return m_pObject;
}
__inline operator TYPE * () const
{
return m_pObject;
}
__inline TYPE * operator ->() const
{
return m_pObject;
}
// declare assignment, but don't implement (compiler error if we try to use)
// that way we can't carelessly mix smart pointers and regular pointers
__inline void * operator =(void *) const;
};
#ifdef _MSC_VER
#pragma warning(pop)
#endif _MSC_VER
#endif // #ifndef APE_SMARTPTR_H