m_spIO;
+
+ WAVEFORMATEX m_wfeSource;
+ int m_nHeaderBytes;
+ int m_nDataBytes;
+ int m_nTerminatingBytes;
+ int m_nFileBytes;
+ BOOL m_bIsValid;
+};
+
+/*************************************************************************************
+Input souce creation
+*************************************************************************************/
+CInputSource * CreateInputSource(const wchar_t * pSourceName, WAVEFORMATEX * pwfeSource, int * pTotalBlocks, int * pHeaderBytes, int * pTerminatingBytes, int * pErrorCode = NULL);
+
+#endif // #ifndef APE_WAVINPUTSOURCE_H
diff --git a/MAC_SDK/Source/MACLib/md5.h b/MAC_SDK/Source/MACLib/md5.h
new file mode 100644
index 0000000..0167ab3
--- /dev/null
+++ b/MAC_SDK/Source/MACLib/md5.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
+ *
+ * License to copy and use this software is granted provided that it is identified
+ * as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing this software or this function.
+ *
+ * License is also granted to make and use derivative works provided that such
+ * works are identified as "derived from the RSA Data Security, Inc. MD5 Message-
+ * Digest Algorithm" in all material mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for any
+ * particular purpose. It is provided "as is" without express or implied warranty
+ * of any kind. These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+#ifndef MD5SUM_MD5_H
+#define MD5SUM_MD5_H
+
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+
+/*
+ * Define the MD5 context structure
+ * Please DO NOT change the order or contents of the structure as various assembler files depend on it !!
+ */
+
+typedef struct {
+ uint32_t state [ 4]; /* state (ABCD) */
+ uint32_t count [ 2]; /* number of bits, modulo 2^64 (least sig word first) */
+ uint8_t buffer [64]; /* input buffer for incomplete buffer data */
+} MD5_CTX;
+
+void MD5Init ( MD5_CTX* ctx );
+void MD5Update ( MD5_CTX* ctx, const uint8_t* buf, size_t len );
+void MD5Final ( uint8_t digest [16], MD5_CTX* ctx );
+
+class CMD5Helper
+{
+public:
+
+ CMD5Helper(BOOL bInitialize = TRUE)
+ {
+ if (bInitialize)
+ Initialize();
+ }
+
+ BOOL Initialize()
+ {
+ memset(&m_MD5Context, 0, sizeof(m_MD5Context));
+ MD5Init(&m_MD5Context);
+ m_nTotalBytes = 0;
+ return TRUE;
+ }
+
+ inline void AddData(const void * pData, int nBytes)
+ {
+ MD5Update(&m_MD5Context, (const unsigned char *) pData, nBytes);
+ m_nTotalBytes += nBytes;
+ }
+
+ BOOL GetResult(unsigned char cResult[16])
+ {
+ memset(cResult, 0, 16);
+ MD5Final(cResult, &m_MD5Context);
+ return TRUE;
+ }
+
+protected:
+
+ MD5_CTX m_MD5Context;
+ BOOL m_bStopped;
+ int m_nTotalBytes;
+};
+
+
+#endif /* MD5SUM_MD5_H */
diff --git a/MAC_SDK/Source/Makefile b/MAC_SDK/Source/Makefile
new file mode 100644
index 0000000..63adbe7
--- /dev/null
+++ b/MAC_SDK/Source/Makefile
@@ -0,0 +1,69 @@
+#
+# Simple Makefile
+#
+# Frank Klemm
+#
+
+TARGET = mac
+INCLUDES = -IShared -IMACLib -IConsole
+CPPOPT = -s -O3 -Wall -pedantic -D__GNUC_IA32__
+COMPILER = gcc
+
+SOURCEFILES = \
+Console/Console.cpp \
+MACLib/APECompress.cpp \
+MACLib/APECompressCore.cpp \
+MACLib/APECompressCreate.cpp \
+MACLib/APEDecompress.cpp \
+MACLib/APEInfo.cpp \
+MACLib/APELink.cpp \
+MACLib/APESimple.cpp \
+MACLib/APETag.cpp \
+MACLib/BitArray.cpp \
+MACLib/MACLib.cpp \
+MACLib/MACProgressHelper.cpp \
+MACLib/NNFilter.cpp \
+MACLib/NewPredictor.cpp \
+MACLib/Prepare.cpp \
+MACLib/UnBitArray.cpp \
+MACLib/UnBitArrayBase.cpp \
+MACLib/WAVInputSource.cpp \
+Shared/GlobalFunctions.cpp \
+Shared/StdLibFileIO.cpp \
+Shared/WinFileIO.cpp \
+MACLib/NNFilterAsm.o
+
+
+
+$(TARGET): $(SOURCEFILES)
+ $(COMPILER) -static $(CPPOPT) $(INCLUDES) -o $(TARGET)-static $(SOURCEFILES)
+ $(COMPILER) $(CPPOPT) $(INCLUDES) -o $(TARGET) $(SOURCEFILES)
+
+MACLib/NNFilterAsm.o : MACLib/NNFilterAsm.nas
+ nasm -f elf -o MACLib/NNFilterAsm.o MACLib/NNFilterAsm.nas -l MACLib/NNFilterAsm.lst
+
+APE_Source.tar.bz2:
+ @sh ./MakeSourceBall
+
+test:
+ @echo e4dd45d9b5ec4cc91f3bd2210a543df6
+ @./$(TARGET) Adagio.ape - -d | md5sum
+
+speed:
+ @sync
+ @cat Adagio.ape > /dev/null
+ @sync
+ time ./mac Adagio.ape /dev/null -d
+
+
+# Samual Barber: Adagio for Strings (10:10.84)
+#
+# C version 203.01 sec
+# First ASM version 76.89 sec
+# 76.85 sec
+# 77.12 sec
+# 76.23 sec
+# 75.67 sec
+# 76.26 sec
+# 76.79 sec
+# 76.70 sec
diff --git a/MAC_SDK/Source/Readme.htm b/MAC_SDK/Source/Readme.htm
new file mode 100644
index 0000000..5f8c51e
--- /dev/null
+++ b/MAC_SDK/Source/Readme.htm
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+Monkey
+
+
+
+
+Monkey's Audio Source Code
+Readme
+(last updated July 7, 2002)
+Introduction
+First off, just to be clear, you have to fully
+agree with the included license agreement before using / viewing any of the
+included materials. The big points are that you can't steal code or try to
+make money with it (without permission) and that you have to submit changes and
+improvements back to the Monkey's Audio project. With that out of the way,
+I'm hoping that by releasing the source code, we'll be able to work together to
+make Monkey's Audio better. Please direct any suggestions or improvements
+to the Monkey's Audio developer's forum or to me personally when appropriate.
+(email @ monkeysaudio.com) And thank you for taking the time to help.
+Important Note
+The Monkey's Audio format is not
+"finalized". In fact, the compression / decompression engines
+are continually being improved. This is what makes MAC fun to work on, and
+it's what makes progress possible. I realize that this can be a pain for
+3rd party developers, but it's the only way to avoid stagnation. So, you
+can not hard code Monkey's Audio support and expect it to work with the newest
+versions of MAC forever. Either use a DLL or else accept that you'll have
+to re-link to MACLib once in a while.
+Things that it'd be great if you worked on
+1. It would be nice to have makefiles for gcc
+or any other compilers that people commonly use.
+2. Pour through the code and look for bone-head
+maneuvers.
+3. Submit any necessary changes for
+cross-platform compilation.
+4. XMMS, Lame DLL, PocketPC, etc. plugins /
+implementations.
+5. A console front-end that doesn't suck. (more
+options, etc.) Also, don't worry about maintaining compatibility with the
+current parameter passing scheme -- just use whatever makes sense.
+Tips for building MACLib outside of Windows
+1. in "Shared/All.h" do this:
+
+ - #define BUILD_CROSS_PLATFORM
+ - look through "Shared/All.h" and
+ "Shared/NoWindows.h" to make sure all the defines are acceptable
+
+2. You need to use NASM to build the assembly
+if you want it. (helps speed a lot) Check out "MacLib/Assembly/..."
+for more information.
+Known non-Windows problems (help fixing them
+would be great)
+2. The macros PUMP_MESSAGE_LOOP, MESSAGEBOX, and a few others don't work.
+
+-
+All materials and programs copyrighted 2000-2002 by Matthew T. Ashland -
+-
+All rights reserved. -
+
+
+
+
diff --git a/MAC_SDK/Source/Shared/APEInfoDialog.cpp b/MAC_SDK/Source/Shared/APEInfoDialog.cpp
new file mode 100644
index 0000000..a4a99da
--- /dev/null
+++ b/MAC_SDK/Source/Shared/APEInfoDialog.cpp
@@ -0,0 +1,308 @@
+#include "All.h"
+#include "APEInfo.h"
+#include "APEInfoDialog.h"
+#include "ID3Genres.h"
+#include "APECompress.h"
+#include "CharacterHelper.h"
+
+/***************************************************************************************
+The dialog component ID's
+***************************************************************************************/
+#define FILE_NAME_EDIT 1000
+
+#define ENCODER_VERSION_STATIC 2000
+#define COMPRESSION_LEVEL_STATIC 2001
+#define FORMAT_FLAGS_STATIC 2002
+#define HAS_TAG_STATIC 2003
+
+#define SAMPLE_RATE_STATIC 3000
+#define CHANNELS_STATIC 3001
+#define BITS_PER_SAMPLE_STATIC 3002
+#define PEAK_LEVEL_STATIC 3003
+
+#define TRACK_LENGTH_STATIC 4000
+#define WAV_SIZE_STATIC 4001
+#define APE_SIZE_STATIC 4002
+#define COMPRESSION_RATIO_STATIC 4003
+
+#define TITLE_EDIT 5000
+#define ARTIST_EDIT 5001
+#define ALBUM_EDIT 5002
+#define COMMENT_EDIT 5003
+#define YEAR_EDIT 5004
+#define GENRE_COMBOBOX 5005
+#define TRACK_EDIT 5006
+
+#define SAVE_TAG_BUTTON 6000
+#define REMOVE_TAG_BUTTON 6001
+#define CANCEL_BUTTON 6002
+
+/***************************************************************************************
+Global pointer to this instance
+***************************************************************************************/
+CAPEInfoDialog * g_pAPEDecompressDialog = NULL;
+
+/***************************************************************************************
+Construction / destruction
+***************************************************************************************/
+CAPEInfoDialog::CAPEInfoDialog()
+{
+ g_pAPEDecompressDialog = NULL;
+}
+
+CAPEInfoDialog::~CAPEInfoDialog()
+{
+
+}
+
+/***************************************************************************************
+Display the file info dialog
+***************************************************************************************/
+int CAPEInfoDialog::ShowAPEInfoDialog(const str_utf16 * pFilename, HINSTANCE hInstance, const str_utf16 * lpszTemplateName, HWND hWndParent)
+{
+ // only allow one instance at a time
+ if (g_pAPEDecompressDialog != NULL) { return -1; }
+
+ // open the file
+ int nErrorCode = ERROR_SUCCESS;
+ m_pAPEDecompress = CreateIAPEDecompress(pFilename, &nErrorCode);
+ if (m_pAPEDecompress == NULL || nErrorCode != ERROR_SUCCESS)
+ return nErrorCode;
+
+ g_pAPEDecompressDialog = this;
+
+ DialogBoxParam(hInstance, lpszTemplateName, hWndParent, (DLGPROC) DialogProc, 0);
+
+ // clean up
+ SAFE_DELETE(m_pAPEDecompress);
+ g_pAPEDecompressDialog = NULL;
+
+ return 0;
+}
+
+/***************************************************************************************
+Fill the genre combobox
+***************************************************************************************/
+int CAPEInfoDialog::FillGenreComboBox(HWND hDlg, int nComboBoxID, char *pSelectedGenre)
+{
+ // declare the variables
+ int nRetVal;
+ HWND hGenreComboBox = GetDlgItem(hDlg, nComboBoxID);
+
+ // reset the contents of the combobox
+ SendMessage(hGenreComboBox, CB_RESETCONTENT, 0, 0);
+
+ // propagate the combobox (0 to 126 so "Undefined" isn't repeated)
+ for (int z = 0; z < GENRE_COUNT; z++)
+ {
+ //add the genre string
+ nRetVal = SendMessage(hGenreComboBox, CB_ADDSTRING, 0, (LPARAM) g_ID3Genre[z]);
+ if (nRetVal == CB_ERR) { return -1; }
+ }
+
+ // add the 'Undefined' genre
+ nRetVal = SendMessage(hGenreComboBox, CB_ADDSTRING, 0, (LPARAM) "Undefined");
+ if (nRetVal == CB_ERR) { return -1; }
+
+ // set the genre id (if it's specified)
+ if (pSelectedGenre)
+ {
+ if (strlen(pSelectedGenre) > 0)
+ SendMessage(hGenreComboBox, CB_SELECTSTRING, -1, (LPARAM) pSelectedGenre);
+ }
+
+ return 0;
+}
+
+/***************************************************************************************
+The dialog procedure
+***************************************************************************************/
+LRESULT CALLBACK CAPEInfoDialog::DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ // get the class
+ IAPEDecompress * pAPEDecompress = g_pAPEDecompressDialog->m_pAPEDecompress;
+
+ int wmID, wmEvent;
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ {
+ // variable declares
+ TCHAR cTemp[1024] = { 0 };
+
+ // set info
+ wchar_t cFilename[MAX_PATH + 1] = {0};
+ GET_IO(pAPEDecompress)->GetName(&cFilename[0]);
+
+ SetDlgItemText(hDlg, FILE_NAME_EDIT, cFilename);
+
+ switch (pAPEDecompress->GetInfo(APE_INFO_COMPRESSION_LEVEL))
+ {
+ case COMPRESSION_LEVEL_FAST: _stprintf(cTemp, _T("Mode: Fast")); break;
+ case COMPRESSION_LEVEL_NORMAL: _stprintf(cTemp, _T("Mode: Normal")); break;
+ case COMPRESSION_LEVEL_HIGH: _stprintf(cTemp, _T("Mode: High")); break;
+ case COMPRESSION_LEVEL_EXTRA_HIGH: _stprintf(cTemp, _T("Mode: Extra High")); break;
+ case COMPRESSION_LEVEL_INSANE: _stprintf(cTemp, _T("Mode: Insane")); break;
+ default: _stprintf(cTemp, _T("Mode: Unknown")); break;
+ }
+ SetDlgItemText(hDlg, COMPRESSION_LEVEL_STATIC, cTemp);
+
+ _stprintf(cTemp, _T("Version: %.2f"), float(pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION)) / float(1000));
+ SetDlgItemText(hDlg, ENCODER_VERSION_STATIC, cTemp);
+
+ _stprintf(cTemp, _T("Format Flags: %d"), pAPEDecompress->GetInfo(APE_INFO_FORMAT_FLAGS));
+ SetDlgItemText(hDlg, FORMAT_FLAGS_STATIC, cTemp);
+
+ _stprintf(cTemp, _T("Sample Rate: %d"), pAPEDecompress->GetInfo(APE_INFO_SAMPLE_RATE));
+ SetDlgItemText(hDlg, SAMPLE_RATE_STATIC, cTemp);
+
+ _stprintf(cTemp, _T("Channels: %d"), pAPEDecompress->GetInfo(APE_INFO_CHANNELS));
+ SetDlgItemText(hDlg, CHANNELS_STATIC, cTemp);
+
+ _stprintf(cTemp, _T("Bits Per Sample: %d"), pAPEDecompress->GetInfo(APE_INFO_BITS_PER_SAMPLE));
+ SetDlgItemText(hDlg, BITS_PER_SAMPLE_STATIC, cTemp);
+
+ int nSeconds = pAPEDecompress->GetInfo(APE_INFO_LENGTH_MS) / 1000; int nMinutes = nSeconds / 60; nSeconds = nSeconds % 60; int nHours = nMinutes / 60; nMinutes = nMinutes % 60;
+ if (nHours > 0) _stprintf(cTemp, _T("Length: %d:%02d:%02d"), nHours, nMinutes, nSeconds);
+ else if (nMinutes > 0) _stprintf(cTemp, _T("Length: %d:%02d"), nMinutes, nSeconds);
+ else _stprintf(cTemp, _T("Length: 0:%02d"), nSeconds);
+ SetDlgItemText(hDlg, TRACK_LENGTH_STATIC, cTemp);
+
+ int nPeakLevel = pAPEDecompress->GetInfo(APE_INFO_PEAK_LEVEL);
+ if (nPeakLevel >= 0) _stprintf(cTemp, _T("Peak Level: %d"), nPeakLevel);
+ else _stprintf(cTemp, _T("Peak Level: ?"));
+ SetDlgItemText(hDlg, PEAK_LEVEL_STATIC, cTemp);
+
+ // the file size
+ _stprintf(cTemp, _T("APE: %.2f MB"), float(pAPEDecompress->GetInfo(APE_INFO_APE_TOTAL_BYTES)) / float(1048576));
+ SetDlgItemText(hDlg, APE_SIZE_STATIC, cTemp);
+
+ _stprintf(cTemp, _T("WAV: %.2f MB"), float(pAPEDecompress->GetInfo(APE_INFO_WAV_TOTAL_BYTES)) / float(1048576));
+ SetDlgItemText(hDlg, WAV_SIZE_STATIC, cTemp);
+
+ // the compression ratio
+ _stprintf(cTemp, _T("Compression: %.2f%%"), float(pAPEDecompress->GetInfo(APE_INFO_AVERAGE_BITRATE) * 100) / float(pAPEDecompress->GetInfo(APE_INFO_DECOMPRESSED_BITRATE)));
+ SetDlgItemText(hDlg, COMPRESSION_RATIO_STATIC, cTemp);
+
+ // the has tag
+ BOOL bHasID3Tag = GET_TAG(pAPEDecompress)->GetHasID3Tag();
+ BOOL bHasAPETag = GET_TAG(pAPEDecompress)->GetHasAPETag();
+
+ if (!bHasID3Tag && !bHasAPETag)
+ _stprintf(cTemp, _T("Tag: None"));
+ else if (bHasID3Tag && !bHasAPETag)
+ _stprintf(cTemp, _T("Tag: ID3v1.1"));
+ else if (!bHasID3Tag && bHasAPETag)
+ _stprintf(cTemp, _T("Tag: APE Tag"));
+ else
+ _stprintf(cTemp, _T("Tag: Corrupt"));
+ SetDlgItemText(hDlg, HAS_TAG_STATIC, cTemp);
+
+ wchar_t cBuffer[256];
+ int nBufferBytes = 256;
+
+ nBufferBytes = 256;
+ GET_TAG(pAPEDecompress)->GetFieldString(APE_TAG_FIELD_TITLE, cBuffer, &nBufferBytes);
+ SetDlgItemText(hDlg, TITLE_EDIT, cBuffer);
+
+ nBufferBytes = 256;
+ GET_TAG(pAPEDecompress)->GetFieldString(APE_TAG_FIELD_ARTIST, cBuffer, &nBufferBytes);
+ SetDlgItemText(hDlg, ARTIST_EDIT, cBuffer);
+
+ nBufferBytes = 256;
+ GET_TAG(pAPEDecompress)->GetFieldString(APE_TAG_FIELD_ALBUM, cBuffer, &nBufferBytes);
+ SetDlgItemText(hDlg, ALBUM_EDIT, cBuffer);
+
+ nBufferBytes = 256;
+ GET_TAG(pAPEDecompress)->GetFieldString(APE_TAG_FIELD_COMMENT, cBuffer, &nBufferBytes);
+ SetDlgItemText(hDlg, COMMENT_EDIT, cBuffer);
+
+ nBufferBytes = 256;
+ GET_TAG(pAPEDecompress)->GetFieldString(APE_TAG_FIELD_YEAR, cBuffer, &nBufferBytes);
+ SetDlgItemText(hDlg, YEAR_EDIT, cBuffer);
+
+ nBufferBytes = 256;
+ GET_TAG(pAPEDecompress)->GetFieldString(APE_TAG_FIELD_TRACK, cBuffer, &nBufferBytes);
+ SetDlgItemText(hDlg, TRACK_EDIT, cBuffer);
+
+ g_pAPEDecompressDialog->FillGenreComboBox(hDlg, GENRE_COMBOBOX, NULL);
+
+ nBufferBytes = 256;
+ GET_TAG(pAPEDecompress)->GetFieldString(APE_TAG_FIELD_GENRE, cBuffer, &nBufferBytes);
+ SetDlgItemText(hDlg, GENRE_COMBOBOX, cBuffer);
+
+ return TRUE;
+ break;
+ }
+ case WM_COMMAND:
+ wmID = LOWORD(wParam);
+ wmEvent = HIWORD(wParam);
+
+ switch (wmID)
+ {
+ case IDCANCEL:
+ // traps the [esc] key
+ EndDialog(hDlg, 0);
+ return TRUE;
+ break;
+ case CANCEL_BUTTON:
+ EndDialog(hDlg, 0);
+ return TRUE;
+ break;
+ case REMOVE_TAG_BUTTON:
+ {
+ // make sure you really wanted to
+ int nRetVal = ::MessageBox(hDlg, _T("Are you sure you want to permanently remove the tag?"), _T("Are You Sure?"), MB_YESNO | MB_ICONQUESTION);
+ if (nRetVal == IDYES)
+ {
+ // remove the ID3 tag...
+ if (GET_TAG(pAPEDecompress)->Remove() != 0)
+ {
+ MessageBox(hDlg, _T("Error removing tag. (could the file be read-only?)"), _T("Error Removing Tag"), MB_OK | MB_ICONEXCLAMATION);
+ return TRUE;
+ }
+ else
+ {
+ EndDialog(hDlg, 0);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ case SAVE_TAG_BUTTON:
+
+ // make the id3 tag
+ TCHAR cBuffer[256]; int z;
+
+ #define SAVE_FIELD(ID, Field) \
+ for (z = 0; z < 256; z++) { cBuffer[z] = 0; } \
+ GetDlgItemText(hDlg, ID, cBuffer, 256); \
+ GET_TAG(pAPEDecompress)->SetFieldString(Field, cBuffer);
+
+ SAVE_FIELD(TITLE_EDIT, APE_TAG_FIELD_TITLE)
+ SAVE_FIELD(ARTIST_EDIT, APE_TAG_FIELD_ARTIST)
+ SAVE_FIELD(ALBUM_EDIT, APE_TAG_FIELD_ALBUM)
+ SAVE_FIELD(COMMENT_EDIT, APE_TAG_FIELD_COMMENT)
+ SAVE_FIELD(TRACK_EDIT, APE_TAG_FIELD_TRACK)
+ SAVE_FIELD(YEAR_EDIT, APE_TAG_FIELD_YEAR)
+ SAVE_FIELD(GENRE_COMBOBOX, APE_TAG_FIELD_GENRE)
+
+ if (GET_TAG(pAPEDecompress)->Save() != 0)
+ {
+ MessageBox(hDlg, _T("Error saving tag. (could the file be read-only?)"), _T("Error Saving Tag"), MB_OK | MB_ICONEXCLAMATION);
+ return TRUE;
+ }
+
+ EndDialog(hDlg, 0);
+ break;
+ }
+ break;
+ case WM_CLOSE:
+ EndDialog(hDlg, 0);
+ return TRUE;
+ break;
+ }
+
+ return FALSE;
+}
\ No newline at end of file
diff --git a/MAC_SDK/Source/Shared/APEInfoDialog.h b/MAC_SDK/Source/Shared/APEInfoDialog.h
new file mode 100644
index 0000000..60a2495
--- /dev/null
+++ b/MAC_SDK/Source/Shared/APEInfoDialog.h
@@ -0,0 +1,22 @@
+#ifndef APE_APEINFODIALOG_H
+#define APE_APEINFODIALOG_H
+
+BOOL CALLBACK FileInfoDialogProcedureA(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+
+class CAPEInfoDialog
+{
+public:
+
+ CAPEInfoDialog();
+ ~CAPEInfoDialog();
+
+ int ShowAPEInfoDialog(const str_utf16 * pFilename, HINSTANCE hInstance, const str_utf16 * lpszTemplateName, HWND hWndParent);
+
+private:
+
+ static LRESULT CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+ int FillGenreComboBox(HWND hDlg, int nComboBoxID, char * pSelectedGenre);
+ IAPEDecompress * m_pAPEDecompress;
+};
+
+#endif // #ifndef APE_APEINFODIALOG_H
\ No newline at end of file
diff --git a/MAC_SDK/Source/Shared/All.h b/MAC_SDK/Source/Shared/All.h
new file mode 100644
index 0000000..fc29b5f
--- /dev/null
+++ b/MAC_SDK/Source/Shared/All.h
@@ -0,0 +1,237 @@
+#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
+#endif
+
+#ifdef _WIN32
+ #include
+ #include
+#else
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include "NoWindows.h"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include "SmartPtr.h"
+
+/*****************************************************************************************
+Global compiler settings (useful for porting)
+*****************************************************************************************/
+#ifndef BUILD_CROSS_PLATFORM
+#ifndef _WIN64
+ #define ENABLE_ASSEMBLY
+#endif
+#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
\ No newline at end of file
diff --git a/MAC_SDK/Source/Shared/CharacterHelper.cpp b/MAC_SDK/Source/Shared/CharacterHelper.cpp
new file mode 100644
index 0000000..fb4bbc6
--- /dev/null
+++ b/MAC_SDK/Source/Shared/CharacterHelper.cpp
@@ -0,0 +1,143 @@
+#include "All.h"
+#include "CharacterHelper.h"
+
+str_ansi * GetANSIFromUTF8(const str_utf8 * pUTF8)
+{
+ str_utf16 * pUTF16 = GetUTF16FromUTF8(pUTF8);
+ str_ansi * pANSI = GetANSIFromUTF16(pUTF16);
+ delete [] pUTF16;
+ return pANSI;
+}
+
+str_ansi * GetANSIFromUTF16(const str_utf16 * pUTF16)
+{
+ const int nCharacters = pUTF16 ? wcslen(pUTF16) : 0;
+ #ifdef _WIN32
+ int nANSICharacters = (2 * nCharacters);
+ str_ansi * pANSI = new str_ansi [nANSICharacters + 1];
+ memset(pANSI, 0, (nANSICharacters + 1) * sizeof(str_ansi));
+ if (pUTF16)
+ WideCharToMultiByte(CP_ACP, 0, pUTF16, -1, pANSI, nANSICharacters, NULL, NULL);
+ #else
+ str_utf8 * pANSI = new str_utf8 [nCharacters + 1];
+ for (int z = 0; z < nCharacters; z++)
+ pANSI[z] = (pUTF16[z] >= 256) ? '?' : (str_utf8) pUTF16[z];
+ pANSI[nCharacters] = 0;
+ #endif
+
+ return (str_ansi *) pANSI;
+}
+
+str_utf16 * GetUTF16FromANSI(const str_ansi * pANSI)
+{
+ const int nCharacters = pANSI ? strlen(pANSI) : 0;
+ str_utf16 * pUTF16 = new str_utf16 [nCharacters + 1];
+
+ #ifdef _WIN32
+ memset(pUTF16, 0, sizeof(str_utf16) * (nCharacters + 1));
+ if (pANSI)
+ MultiByteToWideChar(CP_ACP, 0, pANSI, -1, pUTF16, nCharacters);
+ #else
+ for (int z = 0; z < nCharacters; z++)
+ pUTF16[z] = (str_utf16) ((str_utf8) pANSI[z]);
+ pUTF16[nCharacters] = 0;
+ #endif
+
+ return pUTF16;
+}
+
+str_utf16 * GetUTF16FromUTF8(const str_utf8 * pUTF8)
+{
+ // get the length
+ int nCharacters = 0; int nIndex = 0;
+ while (pUTF8[nIndex] != 0)
+ {
+ if ((pUTF8[nIndex] & 0x80) == 0)
+ nIndex += 1;
+ else if ((pUTF8[nIndex] & 0xE0) == 0xE0)
+ nIndex += 3;
+ else
+ nIndex += 2;
+
+ nCharacters += 1;
+ }
+
+ // make a UTF-16 string
+ str_utf16 * pUTF16 = new str_utf16 [nCharacters + 1];
+ nIndex = 0; nCharacters = 0;
+ while (pUTF8[nIndex] != 0)
+ {
+ if ((pUTF8[nIndex] & 0x80) == 0)
+ {
+ pUTF16[nCharacters] = pUTF8[nIndex];
+ nIndex += 1;
+ }
+ else if ((pUTF8[nIndex] & 0xE0) == 0xE0)
+ {
+ pUTF16[nCharacters] = ((pUTF8[nIndex] & 0x1F) << 12) | ((pUTF8[nIndex + 1] & 0x3F) << 6) | (pUTF8[nIndex + 2] & 0x3F);
+ nIndex += 3;
+ }
+ else
+ {
+ pUTF16[nCharacters] = ((pUTF8[nIndex] & 0x3F) << 6) | (pUTF8[nIndex + 1] & 0x3F);
+ nIndex += 2;
+ }
+
+ nCharacters += 1;
+ }
+ pUTF16[nCharacters] = 0;
+
+ return pUTF16;
+}
+
+str_utf8 * GetUTF8FromANSI(const str_ansi * pANSI)
+{
+ str_utf16 * pUTF16 = GetUTF16FromANSI(pANSI);
+ str_utf8 * pUTF8 = GetUTF8FromUTF16(pUTF16);
+ delete [] pUTF16;
+ return pUTF8;
+}
+
+str_utf8 * GetUTF8FromUTF16(const str_utf16 * pUTF16)
+{
+ // get the size(s)
+ int nCharacters = wcslen(pUTF16);
+ int nUTF8Bytes = 0;
+ for (int z = 0; z < nCharacters; z++)
+ {
+ if (pUTF16[z] < 0x0080)
+ nUTF8Bytes += 1;
+ else if (pUTF16[z] < 0x0800)
+ nUTF8Bytes += 2;
+ else
+ nUTF8Bytes += 3;
+ }
+
+ // allocate a UTF-8 string
+ str_utf8 * pUTF8 = new str_utf8 [nUTF8Bytes + 1];
+
+ // create the UTF-8 string
+ int nUTF8Index = 0;
+ for (int z = 0; z < nCharacters; z++)
+ {
+ if (pUTF16[z] < 0x0080)
+ {
+ pUTF8[nUTF8Index++] = (str_utf8) pUTF16[z];
+ }
+ else if (pUTF16[z] < 0x0800)
+ {
+ pUTF8[nUTF8Index++] = 0xC0 | (pUTF16[z] >> 6);
+ pUTF8[nUTF8Index++] = 0x80 | (pUTF16[z] & 0x3F);
+ }
+ else
+ {
+ pUTF8[nUTF8Index++] = 0xE0 | (pUTF16[z] >> 12);
+ pUTF8[nUTF8Index++] = 0x80 | ((pUTF16[z] >> 6) & 0x3F);
+ pUTF8[nUTF8Index++] = 0x80 | (pUTF16[z] & 0x3F);
+ }
+ }
+ pUTF8[nUTF8Index++] = 0;
+
+ // return the UTF-8 string
+ return pUTF8;
+}
\ No newline at end of file
diff --git a/MAC_SDK/Source/Shared/CharacterHelper.h b/MAC_SDK/Source/Shared/CharacterHelper.h
new file mode 100644
index 0000000..6f63a1e
--- /dev/null
+++ b/MAC_SDK/Source/Shared/CharacterHelper.h
@@ -0,0 +1,15 @@
+/*******************************************************************************************
+Character set conversion helpers
+*******************************************************************************************/
+
+#ifndef CHARACTER_HELPER_H
+#define CHARACTER_HELPER_H
+
+str_ansi * GetANSIFromUTF8(const str_utf8 * pUTF8);
+str_ansi * GetANSIFromUTF16(const str_utf16 * pUTF16);
+str_utf16 * GetUTF16FromANSI(const str_ansi * pANSI);
+str_utf16 * GetUTF16FromUTF8(const str_utf8 * pUTF8);
+str_utf8 * GetUTF8FromANSI(const str_ansi * pANSI);
+str_utf8 * GetUTF8FromUTF16(const str_utf16 * pUTF16);
+
+#endif // #ifndef CHARACTER_HELPER_H
\ No newline at end of file
diff --git a/MAC_SDK/Source/Shared/CircleBuffer.cpp b/MAC_SDK/Source/Shared/CircleBuffer.cpp
new file mode 100644
index 0000000..7ed9ec2
--- /dev/null
+++ b/MAC_SDK/Source/Shared/CircleBuffer.cpp
@@ -0,0 +1,89 @@
+#include "All.h"
+#include "CircleBuffer.h"
+
+CCircleBuffer::CCircleBuffer()
+{
+ m_pBuffer = NULL;
+ m_nTotal = 0;
+ m_nHead = 0;
+ m_nTail = 0;
+ m_nEndCap = 0;
+ m_nMaxDirectWriteBytes = 0;
+}
+
+CCircleBuffer::~CCircleBuffer()
+{
+ SAFE_ARRAY_DELETE(m_pBuffer)
+}
+
+void CCircleBuffer::CreateBuffer(int nBytes, int nMaxDirectWriteBytes)
+{
+ SAFE_ARRAY_DELETE(m_pBuffer)
+
+ m_nMaxDirectWriteBytes = nMaxDirectWriteBytes;
+ m_nTotal = nBytes + 1 + nMaxDirectWriteBytes;
+ m_pBuffer = new unsigned char [m_nTotal];
+ m_nHead = 0;
+ m_nTail = 0;
+ m_nEndCap = m_nTotal;
+}
+
+int CCircleBuffer::MaxAdd()
+{
+ int nMaxAdd = (m_nTail >= m_nHead) ? (m_nTotal - 1 - m_nMaxDirectWriteBytes) - (m_nTail - m_nHead) : m_nHead - m_nTail - 1;
+ return nMaxAdd;
+}
+
+int CCircleBuffer::MaxGet()
+{
+ return (m_nTail >= m_nHead) ? m_nTail - m_nHead : (m_nEndCap - m_nHead) + m_nTail;
+}
+
+int CCircleBuffer::Get(unsigned char * pBuffer, int nBytes)
+{
+ int nTotalGetBytes = 0;
+
+ if (pBuffer != NULL && nBytes > 0)
+ {
+ int nHeadBytes = min(m_nEndCap - m_nHead, nBytes);
+ int nFrontBytes = nBytes - nHeadBytes;
+
+ memcpy(&pBuffer[0], &m_pBuffer[m_nHead], nHeadBytes);
+ nTotalGetBytes = nHeadBytes;
+
+ if (nFrontBytes > 0)
+ {
+ memcpy(&pBuffer[nHeadBytes], &m_pBuffer[0], nFrontBytes);
+ nTotalGetBytes += nFrontBytes;
+ }
+
+ RemoveHead(nBytes);
+ }
+
+ return nTotalGetBytes;
+}
+
+void CCircleBuffer::Empty()
+{
+ m_nHead = 0;
+ m_nTail = 0;
+ m_nEndCap = m_nTotal;
+}
+
+int CCircleBuffer::RemoveHead(int nBytes)
+{
+ nBytes = min(MaxGet(), nBytes);
+ m_nHead += nBytes;
+ if (m_nHead >= m_nEndCap)
+ m_nHead -= m_nEndCap;
+ return nBytes;
+}
+
+int CCircleBuffer::RemoveTail(int nBytes)
+{
+ nBytes = min(MaxGet(), nBytes);
+ m_nTail -= nBytes;
+ if (m_nTail < 0)
+ m_nTail += m_nEndCap;
+ return nBytes;
+}
diff --git a/MAC_SDK/Source/Shared/CircleBuffer.h b/MAC_SDK/Source/Shared/CircleBuffer.h
new file mode 100644
index 0000000..3d008dd
--- /dev/null
+++ b/MAC_SDK/Source/Shared/CircleBuffer.h
@@ -0,0 +1,59 @@
+#ifndef APE_CIRCLEBUFFER_H
+#define APE_CIRCLEBUFFER_H
+
+class CCircleBuffer
+{
+public:
+
+ // construction / destruction
+ CCircleBuffer();
+ virtual ~CCircleBuffer();
+
+ // create the buffer
+ void CreateBuffer(int nBytes, int nMaxDirectWriteBytes);
+
+ // query
+ int MaxAdd();
+ int MaxGet();
+
+ // direct writing
+ inline unsigned char * CCircleBuffer::GetDirectWritePointer()
+ {
+ // return a pointer to the tail -- note that it will always be safe to write
+ // at least m_nMaxDirectWriteBytes since we use an end cap region
+ return &m_pBuffer[m_nTail];
+ }
+
+ inline void CCircleBuffer::UpdateAfterDirectWrite(int nBytes)
+ {
+ // update the tail
+ m_nTail += nBytes;
+
+ // if the tail enters the "end cap" area, set the end cap and loop around
+ if (m_nTail >= (m_nTotal - m_nMaxDirectWriteBytes))
+ {
+ m_nEndCap = m_nTail;
+ m_nTail = 0;
+ }
+ }
+
+ // get data
+ int Get(unsigned char * pBuffer, int nBytes);
+
+ // remove / empty
+ void Empty();
+ int RemoveHead(int nBytes);
+ int RemoveTail(int nBytes);
+
+private:
+
+ int m_nTotal;
+ int m_nMaxDirectWriteBytes;
+ int m_nEndCap;
+ int m_nHead;
+ int m_nTail;
+ unsigned char * m_pBuffer;
+};
+
+
+#endif // #ifndef APE_CIRCLEBUFFER_H
diff --git a/MAC_SDK/Source/Shared/GlobalFunctions.cpp b/MAC_SDK/Source/Shared/GlobalFunctions.cpp
new file mode 100644
index 0000000..5f0b578
--- /dev/null
+++ b/MAC_SDK/Source/Shared/GlobalFunctions.cpp
@@ -0,0 +1,100 @@
+#include "All.h"
+#include "GlobalFunctions.h"
+#include "IO.h"
+
+/*
+#ifndef __GNUC_IA32__
+
+extern "C" BOOL GetMMXAvailable(void)
+{
+#ifdef ENABLE_ASSEMBLY
+
+ unsigned long nRegisterEDX;
+
+ try
+ {
+ __asm mov eax, 1
+ __asm CPUID
+ __asm mov nRegisterEDX, edx
+ }
+ catch(...)
+ {
+ return FALSE;
+ }
+
+ if (nRegisterEDX & 0x800000)
+ RETURN_ON_EXCEPTION(__asm emms, FALSE)
+ else
+ return FALSE;
+
+ return TRUE;
+
+#else
+ return FALSE;
+#endif
+}
+
+#endif // #ifndef __GNUC_IA32__
+*/
+
+int ReadSafe(CIO * pIO, void * pBuffer, int nBytes)
+{
+ unsigned int nBytesRead = 0;
+ int nRetVal = pIO->Read(pBuffer, nBytes, &nBytesRead);
+ if (nRetVal == ERROR_SUCCESS)
+ {
+ if (nBytes != int(nBytesRead))
+ nRetVal = ERROR_IO_READ;
+ }
+
+ return nRetVal;
+}
+
+int WriteSafe(CIO * pIO, void * pBuffer, int nBytes)
+{
+ unsigned int nBytesWritten = 0;
+ int nRetVal = pIO->Write(pBuffer, nBytes, &nBytesWritten);
+ if (nRetVal == ERROR_SUCCESS)
+ {
+ if (nBytes != int(nBytesWritten))
+ nRetVal = ERROR_IO_WRITE;
+ }
+
+ return nRetVal;
+}
+
+BOOL FileExists(wchar_t * pFilename)
+{
+ if (0 == wcscmp(pFilename, L"-") || 0 == wcscmp(pFilename, L"/dev/stdin"))
+ return TRUE;
+
+#ifdef _WIN32
+
+ BOOL bFound = FALSE;
+
+ WIN32_FIND_DATA WFD;
+ HANDLE hFind = FindFirstFile(pFilename, &WFD);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ bFound = TRUE;
+ CloseHandle(hFind);
+ }
+
+ return bFound;
+
+#else
+
+ CSmartPtr spANSI(GetANSIFromUTF16(pFilename), TRUE);
+
+ struct stat b;
+
+ if (stat(spANSI, &b) != 0)
+ return FALSE;
+
+ if (!S_ISREG(b.st_mode))
+ return FALSE;
+
+ return TRUE;
+
+#endif
+}
\ No newline at end of file
diff --git a/MAC_SDK/Source/Shared/GlobalFunctions.h b/MAC_SDK/Source/Shared/GlobalFunctions.h
new file mode 100644
index 0000000..0928cbb
--- /dev/null
+++ b/MAC_SDK/Source/Shared/GlobalFunctions.h
@@ -0,0 +1,21 @@
+#ifndef APE_GLOBALFUNCTIONS_H
+#define APE_GLOBALFUNCTIONS_H
+
+/*************************************************************************************
+Definitions
+*************************************************************************************/
+class CIO;
+
+/*************************************************************************************
+Read / Write from an IO source and return failure if the number of bytes specified
+isn't read or written
+*************************************************************************************/
+int ReadSafe(CIO * pIO, void * pBuffer, int nBytes);
+int WriteSafe(CIO * pIO, void * pBuffer, int nBytes);
+
+/*************************************************************************************
+Checks for the existence of a file
+*************************************************************************************/
+BOOL FileExists(wchar_t * pFilename);
+
+#endif // #ifndef APE_GLOBALFUNCTIONS_H
diff --git a/MAC_SDK/Source/Shared/ID3Genres.h b/MAC_SDK/Source/Shared/ID3Genres.h
new file mode 100644
index 0000000..aa168ee
--- /dev/null
+++ b/MAC_SDK/Source/Shared/ID3Genres.h
@@ -0,0 +1,27 @@
+#ifndef APE_ID3GENRES_H
+#define APE_ID3GENRES_H
+
+#define GENRE_UNDEFINED 255
+#define GENRE_COUNT 148
+
+const LPCWSTR g_ID3Genre[GENRE_COUNT] =
+{
+ L"Blues", L"Classic Rock", L"Country", L"Dance", L"Disco", L"Funk", L"Grunge", L"Hip-Hop",
+ L"Jazz", L"Metal", L"New Age", L"Oldies", L"Other", L"Pop", L"R&B", L"Rap", L"Reggae", L"Rock", L"Techno",
+ L"Industrial", L"Alternative", L"Ska", L"Death Metal", L"Pranks", L"Soundtrack", L"Euro-Techno", L"Ambient",
+ L"Trip-Hop", L"Vocal", L"Jazz+Funk", L"Fusion", L"Trance", L"Classical", L"Instrumental", L"Acid", L"House", L"Game",
+ L"Sound Clip", L"Gospel", L"Noise", L"AlternRock", L"Bass", L"Soul", L"Punk", L"Space", L"Meditative", L"Instrumental Pop",
+ L"Instrumental Rock", L"Ethnic", L"Gothic", L"Darkwave", L"Techno-Industrial", L"Electronic", L"Pop-Folk", L"Eurodance",
+ L"Dream", L"Southern Rock", L"Comedy", L"Cult", L"Gangsta", L"Top 40", L"Christian Rap", L"Pop/Funk", L"Jungle",
+ L"Native American", L"Cabaret", L"New Wave", L"Psychadelic", L"Rave", L"Showtunes", L"Trailer", L"Lo-Fi", L"Tribal",
+ L"Acid Punk", L"Acid Jazz", L"Polka", L"Retro", L"Musical", L"Rock & Roll", L"Hard Rock", L"Folk", L"Folk-Rock", L"National Folk",
+ L"Swing", L"Fast Fusion", L"Bebop", L"Latin", L"Revival", L"Celtic", L"Bluegrass", L"Avantgarde", L"Gothic Rock", L"Progressive Rock",
+ L"Psychedelic Rock", L"Symphonic Rock", L"Slow Rock", L"Big Band", L"Chorus", L"Easy Listening", L"Acoustic", L"Humour",
+ L"Speech", L"Chanson", L"Opera", L"Chamber Music", L"Sonata", L"Symphony", L"Booty Bass", L"Primus", L"Porn Groove",
+ L"Satire", L"Slow Jam", L"Club", L"Tango", L"Samba", L"Folklore", L"Ballad", L"Power Ballad", L"Rhythmic Soul", L"Freestyle",
+ L"Duet", L"Punk Rock", L"Drum Solo", L"Acapella", L"Euro-House", L"Dance Hall", L"Goa", L"Drum & Bass", L"Club House", L"Hardcore",
+ L"Terror", L"Indie", L"BritPop", L"Black Punk", L"Polsk Punk", L"Beat", L"Christian Gangsta", L"Heavy Metal", L"Black Metal",
+ L"Crossover", L"Contemporary C", L"Christian Rock", L"Merengue", L"Salsa", L"Thrash Metal", L"Anime", L"JPop", L"SynthPop"
+};
+
+#endif // #ifndef APE_ID3GENRES_H
diff --git a/MAC_SDK/Source/Shared/IO.h b/MAC_SDK/Source/Shared/IO.h
new file mode 100644
index 0000000..63b4d7f
--- /dev/null
+++ b/MAC_SDK/Source/Shared/IO.h
@@ -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
diff --git a/MAC_SDK/Source/Shared/NoWindows.h b/MAC_SDK/Source/Shared/NoWindows.h
new file mode 100644
index 0000000..e6519d7
--- /dev/null
+++ b/MAC_SDK/Source/Shared/NoWindows.h
@@ -0,0 +1,68 @@
+#ifndef _WIN32
+
+#ifndef APE_NOWINDOWS_H
+#define APE_NOWINDOWS_H
+
+#define FALSE 0
+#define TRUE 1
+
+#define NEAR
+#define FAR
+
+typedef unsigned int uint32;
+typedef int int32;
+typedef unsigned short uint16;
+typedef short int16;
+typedef unsigned char uint8;
+typedef char int8;
+typedef char str_ansi;
+typedef unsigned char str_utf8;
+typedef wchar_t str_utf16;
+
+typedef unsigned long DWORD;
+typedef int BOOL;
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef float FLOAT;
+typedef void * HANDLE;
+typedef unsigned int UINT;
+typedef unsigned int WPARAM;
+typedef long LPARAM;
+typedef const char * LPCSTR;
+typedef char * LPSTR;
+typedef long LRESULT;
+
+#define ZeroMemory(POINTER, BYTES) memset(POINTER, 0, BYTES);
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+#define __stdcall
+#define CALLBACK
+
+#define _stricmp strcasecmp
+#define _strnicmp strncasecmp
+
+#define _FPOSOFF(fp) ((long)(fp).__pos)
+#define MAX_PATH 260
+
+#ifndef _WAVEFORMATEX_
+#define _WAVEFORMATEX_
+
+typedef struct tWAVEFORMATEX
+{
+ WORD wFormatTag; /* format type */
+ WORD nChannels; /* number of channels (i.e. mono, stereo...) */
+ DWORD nSamplesPerSec; /* sample rate */
+ DWORD nAvgBytesPerSec; /* for buffer estimation */
+ WORD nBlockAlign; /* block size of data */
+ WORD wBitsPerSample; /* number of bits per sample of mono data */
+ WORD cbSize; /* the count in bytes of the size of */
+ /* extra information (after cbSize) */
+} WAVEFORMATEX, *PWAVEFORMATEX, NEAR *NPWAVEFORMATEX, FAR *LPWAVEFORMATEX;
+typedef const WAVEFORMATEX FAR *LPCWAVEFORMATEX;
+
+#endif // #ifndef _WAVEFORMATEX_
+
+#endif // #ifndef APE_NOWINDOWS_H
+
+#endif // #ifndef _WIN32
diff --git a/MAC_SDK/Source/Shared/RollBuffer.h b/MAC_SDK/Source/Shared/RollBuffer.h
new file mode 100644
index 0000000..0c5b8e0
--- /dev/null
+++ b/MAC_SDK/Source/Shared/RollBuffer.h
@@ -0,0 +1,120 @@
+#ifndef APE_ROLLBUFFER_H
+#define APE_ROLLBUFFER_H
+
+template class CRollBuffer
+{
+public:
+
+ CRollBuffer()
+ {
+ m_pData = NULL;
+ m_pCurrent = NULL;
+ }
+
+ ~CRollBuffer()
+ {
+ SAFE_ARRAY_DELETE(m_pData);
+ }
+
+ int Create(int nWindowElements, int nHistoryElements)
+ {
+ SAFE_ARRAY_DELETE(m_pData)
+ m_nWindowElements = nWindowElements;
+ m_nHistoryElements = nHistoryElements;
+
+ m_pData = new TYPE[m_nWindowElements + m_nHistoryElements];
+ if (m_pData == NULL)
+ return ERROR_INSUFFICIENT_MEMORY;
+
+ Flush();
+ return 0;
+ }
+
+ void Flush()
+ {
+ ZeroMemory(m_pData, (m_nHistoryElements + 1) * sizeof(TYPE));
+ m_pCurrent = &m_pData[m_nHistoryElements];
+ }
+
+ void Roll()
+ {
+ memcpy(&m_pData[0], &m_pCurrent[-m_nHistoryElements], m_nHistoryElements * sizeof(TYPE));
+ m_pCurrent = &m_pData[m_nHistoryElements];
+ }
+
+ __inline void IncrementSafe()
+ {
+ m_pCurrent++;
+ if (m_pCurrent == &m_pData[m_nWindowElements + m_nHistoryElements])
+ Roll();
+ }
+
+ __inline void IncrementFast()
+ {
+ m_pCurrent++;
+ }
+
+ __inline TYPE & operator[](const int nIndex) const
+ {
+ return m_pCurrent[nIndex];
+ }
+
+protected:
+
+ TYPE * m_pData;
+ TYPE * m_pCurrent;
+ int m_nHistoryElements;
+ int m_nWindowElements;
+};
+
+template class CRollBufferFast
+{
+public:
+
+ CRollBufferFast()
+ {
+ m_pData = new TYPE[WINDOW_ELEMENTS + HISTORY_ELEMENTS];
+ Flush();
+ }
+
+ ~CRollBufferFast()
+ {
+ SAFE_ARRAY_DELETE(m_pData);
+ }
+
+ void Flush()
+ {
+ ZeroMemory(m_pData, (HISTORY_ELEMENTS + 1) * sizeof(TYPE));
+ m_pCurrent = &m_pData[HISTORY_ELEMENTS];
+ }
+
+ void Roll()
+ {
+ memcpy(&m_pData[0], &m_pCurrent[-HISTORY_ELEMENTS], HISTORY_ELEMENTS * sizeof(TYPE));
+ m_pCurrent = &m_pData[HISTORY_ELEMENTS];
+ }
+
+ __inline void IncrementSafe()
+ {
+ m_pCurrent++;
+ if (m_pCurrent == &m_pData[WINDOW_ELEMENTS + HISTORY_ELEMENTS])
+ Roll();
+ }
+
+ __inline void IncrementFast()
+ {
+ m_pCurrent++;
+ }
+
+ __inline TYPE & operator[](const int nIndex) const
+ {
+ return m_pCurrent[nIndex];
+ }
+
+protected:
+
+ TYPE * m_pData;
+ TYPE * m_pCurrent;
+};
+
+#endif // #ifndef APE_ROLLBUFFER_H
diff --git a/MAC_SDK/Source/Shared/SmartPtr.h b/MAC_SDK/Source/Shared/SmartPtr.h
new file mode 100644
index 0000000..c9bb9be
--- /dev/null
+++ b/MAC_SDK/Source/Shared/SmartPtr.h
@@ -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 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
diff --git a/MAC_SDK/Source/Shared/StdLibFileIO.cpp b/MAC_SDK/Source/Shared/StdLibFileIO.cpp
new file mode 100644
index 0000000..5f59069
--- /dev/null
+++ b/MAC_SDK/Source/Shared/StdLibFileIO.cpp
@@ -0,0 +1,239 @@
+#include "All.h"
+
+#ifdef IO_USE_STD_LIB_FILE_IO
+
+#include "StdLibFileIO.h"
+
+///////////////////////////////////////////////////////
+
+// low level I/O, where are prototypes and constants?
+#if defined _WIN32 || defined __TURBOC__ || defined __ZTC__ || defined _MSC_VER
+# include
+# include
+# include
+# include
+# include
+#elif defined __unix__ || defined __linux__
+# include
+# include
+# include
+# include