From a811cfd012a56589c1c29a59f1a4f2ef1377382b Mon Sep 17 00:00:00 2001 From: Grigory Chudov Date: Fri, 16 Mar 2018 00:12:34 -0400 Subject: [PATCH] Update MAC_SDK to 4.33 --- .gitignore | 8 +- .gitmodules | 3 + CUETools.Codecs.APE/CUETools.Codecs.APE.cpp | 51 +- .../CUETools.Codecs.APE.vcxproj | 15 +- CUETools.eac3to/Program.cs | 107 +- CUETools/CUETools.sln | 40 +- .../TMonkey (Delphi)/APEtag/APEtag.pas | 488 --- .../TMonkey (Delphi)/APEtag/Info.txt | 18 - .../TMonkey (Delphi)/APEtag/Main.dfm | Bin 5596 -> 0 bytes .../TMonkey (Delphi)/APEtag/Main.pas | 159 - .../TMonkey (Delphi)/APEtag/Test.cfg | 35 - .../TMonkey (Delphi)/APEtag/Test.dof | 96 - .../TMonkey (Delphi)/APEtag/Test.dpr | 15 - .../TMonkey (Delphi)/APEtag/Test.res | Bin 3780 -> 0 bytes .../TMonkey (Delphi)/ID3v1/ID3v1.pas | 475 --- .../3rd Party/TMonkey (Delphi)/ID3v1/Info.txt | 17 - .../3rd Party/TMonkey (Delphi)/ID3v1/Main.dfm | Bin 7324 -> 0 bytes .../3rd Party/TMonkey (Delphi)/ID3v1/Main.pas | 162 - .../3rd Party/TMonkey (Delphi)/ID3v1/Test.cfg | 35 - .../3rd Party/TMonkey (Delphi)/ID3v1/Test.dof | 96 - .../3rd Party/TMonkey (Delphi)/ID3v1/Test.dpr | 15 - .../3rd Party/TMonkey (Delphi)/ID3v1/Test.res | Bin 3780 -> 0 bytes .../TMonkey (Delphi)/ID3v2/ID3v2.pas | 631 ---- .../3rd Party/TMonkey (Delphi)/ID3v2/Info.txt | 32 - .../3rd Party/TMonkey (Delphi)/ID3v2/Main.dfm | Bin 6378 -> 0 bytes .../3rd Party/TMonkey (Delphi)/ID3v2/Main.pas | 179 - .../3rd Party/TMonkey (Delphi)/ID3v2/Test.cfg | 35 - .../3rd Party/TMonkey (Delphi)/ID3v2/Test.dof | 96 - .../3rd Party/TMonkey (Delphi)/ID3v2/Test.dpr | 15 - .../3rd Party/TMonkey (Delphi)/ID3v2/Test.res | Bin 3780 -> 0 bytes .../TMonkey (Delphi)/Monkey/Info.txt | 30 - .../TMonkey (Delphi)/Monkey/Main.dfm | Bin 5770 -> 0 bytes .../TMonkey (Delphi)/Monkey/Main.pas | 131 - .../TMonkey (Delphi)/Monkey/Monkey.pas | 300 -- .../TMonkey (Delphi)/Monkey/Test.cfg | 35 - .../TMonkey (Delphi)/Monkey/Test.dof | 96 - .../TMonkey (Delphi)/Monkey/Test.dpr | 18 - .../TMonkey (Delphi)/Monkey/Test.res | Bin 3780 -> 0 bytes MAC_SDK/3rd Party/TMonkey (Delphi)/Readme.txt | 5 - MAC_SDK/Analyze/Sample 1/Sample 1.cpp | 127 - MAC_SDK/Analyze/Sample 1/Sample 1.dsp | 102 - MAC_SDK/Compress/Sample 1/Sample 1.cpp | 121 - MAC_SDK/Compress/Sample 1/Sample 1.dsp | 106 - MAC_SDK/Compress/Sample 2/Sample 2.cpp | 217 -- MAC_SDK/Compress/Sample 2/Sample 2.dsp | 100 - MAC_SDK/Decompress/Sample 1/Sample 1.cpp | 92 - MAC_SDK/Decompress/Sample 1/Sample 1.dsp | 110 - MAC_SDK/Decompress/Sample 1/Sample 1.vcproj | 460 --- MAC_SDK/Decompress/Sample 2/Sample 2.cpp | 117 - MAC_SDK/Decompress/Sample 2/Sample 2.dsp | 114 - MAC_SDK/Decompress/Sample 2/Sample 2.vcproj | 461 --- MAC_SDK/Decompress/Sample 3/Sample 3.cpp | 190 -- MAC_SDK/Decompress/Sample 3/Sample 3.dsp | 115 - MAC_SDK/Decompress/Sample 3/Sample 3.vcproj | 451 --- MAC_SDK/Shared/APETag.h | 293 -- MAC_SDK/Shared/All.h | 235 -- MAC_SDK/Shared/IO.h | 49 - MAC_SDK/Shared/MACDll.h | 99 - MAC_SDK/Shared/MACLib.h | 452 --- MAC_SDK/Shared/SmartPtr.h | 89 - MAC_SDK/Source/Console/Console.cpp | 190 -- MAC_SDK/Source/Console/Console.dsp | 114 - MAC_SDK/Source/Console/Console.vcproj | 185 - MAC_SDK/Source/Console/Resource Script.rc | 103 - MAC_SDK/Source/Console/resource.h | 15 - MAC_SDK/Source/Credits.txt | 25 - MAC_SDK/Source/History.txt | 79 - MAC_SDK/Source/License.htm | 48 - MAC_SDK/Source/MACDll/MACDll.cpp | 233 -- MAC_SDK/Source/MACDll/MACDll.def | 38 - MAC_SDK/Source/MACDll/MACDll.dsp | 160 - MAC_SDK/Source/MACDll/MACDll.h | 99 - MAC_SDK/Source/MACDll/MACDll.vcproj | 261 -- MAC_SDK/Source/MACDll/Monkey Head (1).ico | Bin 2238 -> 0 bytes MAC_SDK/Source/MACDll/Monkey Head.ico | Bin 2238 -> 0 bytes MAC_SDK/Source/MACDll/Resource Script.rc | 226 -- MAC_SDK/Source/MACDll/resource.h | 20 - MAC_SDK/Source/MACLib/APECompress.cpp | 250 -- MAC_SDK/Source/MACLib/APECompress.h | 58 - MAC_SDK/Source/MACLib/APECompressCore.cpp | 126 - MAC_SDK/Source/MACLib/APECompressCore.h | 41 - MAC_SDK/Source/MACLib/APECompressCreate.cpp | 218 -- MAC_SDK/Source/MACLib/APECompressCreate.h | 43 - MAC_SDK/Source/MACLib/APEDecompress.cpp | 479 --- MAC_SDK/Source/MACLib/APEDecompress.h | 72 - MAC_SDK/Source/MACLib/APEHeader.cpp | 280 -- MAC_SDK/Source/MACLib/APEHeader.h | 57 - MAC_SDK/Source/MACLib/APEInfo.cpp | 374 -- MAC_SDK/Source/MACLib/APEInfo.h | 106 - MAC_SDK/Source/MACLib/APELink.cpp | 120 - MAC_SDK/Source/MACLib/APELink.h | 30 - MAC_SDK/Source/MACLib/APESimple.cpp | 430 --- MAC_SDK/Source/MACLib/APETag.cpp | 745 ---- MAC_SDK/Source/MACLib/APETag.h | 293 -- MAC_SDK/Source/MACLib/Assembly/Assembly.h | 12 - MAC_SDK/Source/MACLib/Assembly/Assembly.nas | 181 - MAC_SDK/Source/MACLib/Assembly/Assembly.obj | Bin 818 -> 0 bytes MAC_SDK/Source/MACLib/Assembly/Assembly64.nas | 194 -- MAC_SDK/Source/MACLib/Assembly/Assembly64.obj | Bin 1224 -> 0 bytes MAC_SDK/Source/MACLib/Assembly/Tools.inc | 117 - MAC_SDK/Source/MACLib/Assembly/Tools64.inc | 119 - MAC_SDK/Source/MACLib/BitArray.cpp | 434 --- MAC_SDK/Source/MACLib/BitArray.h | 62 - MAC_SDK/Source/MACLib/MACLib.cpp | 163 - MAC_SDK/Source/MACLib/MACLib.dsp | 462 --- MAC_SDK/Source/MACLib/MACLib.h | 452 --- MAC_SDK/Source/MACLib/MACLib.sln | 34 - MAC_SDK/Source/MACLib/MACLib.vcproj | 1334 -------- MAC_SDK/Source/MACLib/MACLib.vcproj.7.10.old | 1019 ------ MAC_SDK/Source/MACLib/MACLib.vcxproj | 581 ---- MAC_SDK/Source/MACLib/MACProgressHelper.cpp | 82 - MAC_SDK/Source/MACLib/MACProgressHelper.h | 37 - MAC_SDK/Source/MACLib/MD5.cpp | 264 -- MAC_SDK/Source/MACLib/MultichannelNNFilter.h | 95 - MAC_SDK/Source/MACLib/NNFilter.cpp | 168 - MAC_SDK/Source/MACLib/NNFilter.h | 42 - MAC_SDK/Source/MACLib/NewPredictor.cpp | 408 --- MAC_SDK/Source/MACLib/NewPredictor.h | 111 - .../Source/MACLib/Old/APEDecompressCore.cpp | 178 - MAC_SDK/Source/MACLib/Old/APEDecompressCore.h | 37 - .../Source/MACLib/Old/APEDecompressOld.cpp | 279 -- MAC_SDK/Source/MACLib/Old/APEDecompressOld.h | 43 - MAC_SDK/Source/MACLib/Old/Anti-Predictor.cpp | 394 --- MAC_SDK/Source/MACLib/Old/Anti-Predictor.h | 253 -- .../MACLib/Old/AntiPredictorExtraHigh.cpp | 330 -- .../Source/MACLib/Old/AntiPredictorFast.cpp | 88 - .../Source/MACLib/Old/AntiPredictorHigh.cpp | 484 --- .../Source/MACLib/Old/AntiPredictorNormal.cpp | 262 -- MAC_SDK/Source/MACLib/Old/UnBitArrayOld.cpp | 353 -- MAC_SDK/Source/MACLib/Old/UnBitArrayOld.h | 46 - MAC_SDK/Source/MACLib/Old/UnMAC.cpp | 261 -- MAC_SDK/Source/MACLib/Old/UnMAC.h | 69 - MAC_SDK/Source/MACLib/Predictor.h | 30 - MAC_SDK/Source/MACLib/Prepare.cpp | 510 --- MAC_SDK/Source/MACLib/Prepare.h | 38 - .../Source/MACLib/ScaledFirstOrderFilter.h | 31 - MAC_SDK/Source/MACLib/StartFilter.h | 178 - MAC_SDK/Source/MACLib/UnBitArray.cpp | 302 -- MAC_SDK/Source/MACLib/UnBitArray.h | 51 - MAC_SDK/Source/MACLib/UnBitArrayBase.cpp | 112 - MAC_SDK/Source/MACLib/UnBitArrayBase.h | 59 - MAC_SDK/Source/MACLib/WAVInputSource.cpp | 279 -- MAC_SDK/Source/MACLib/WAVInputSource.h | 64 - MAC_SDK/Source/MACLib/md5.h | 79 - MAC_SDK/Source/Makefile | 69 - MAC_SDK/Source/Readme.htm | 67 - MAC_SDK/Source/Shared/APEInfoDialog.cpp | 308 -- MAC_SDK/Source/Shared/APEInfoDialog.h | 22 - MAC_SDK/Source/Shared/All.h | 237 -- MAC_SDK/Source/Shared/CharacterHelper.cpp | 143 - MAC_SDK/Source/Shared/CharacterHelper.h | 15 - MAC_SDK/Source/Shared/CircleBuffer.cpp | 89 - MAC_SDK/Source/Shared/CircleBuffer.h | 59 - MAC_SDK/Source/Shared/GlobalFunctions.cpp | 100 - MAC_SDK/Source/Shared/GlobalFunctions.h | 21 - MAC_SDK/Source/Shared/ID3Genres.h | 27 - MAC_SDK/Source/Shared/IO.h | 49 - MAC_SDK/Source/Shared/NoWindows.h | 68 - MAC_SDK/Source/Shared/RollBuffer.h | 120 - MAC_SDK/Source/Shared/SmartPtr.h | 89 - MAC_SDK/Source/Shared/StdLibFileIO.cpp | 239 -- MAC_SDK/Source/Shared/StdLibFileIO.h | 50 - MAC_SDK/Source/Shared/StdString.h | 3015 ----------------- MAC_SDK/Source/Shared/Unicows.cpp | 18 - MAC_SDK/Source/Shared/WAVInfoDialog.cpp | 156 - MAC_SDK/Source/Shared/WAVInfoDialog.h | 22 - MAC_SDK/Source/Shared/WinFileIO.cpp | 164 - MAC_SDK/Source/Shared/WinFileIO.h | 49 - ThirdParty/MAC_SDK | 1 + ThirdPartyDebug/x64/MACLib.lib | Bin 0 -> 1792320 bytes ThirdPartyDebug/x64/MACLib.pdb | Bin 0 -> 282624 bytes 171 files changed, 113 insertions(+), 29321 deletions(-) delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/APEtag.pas delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Info.txt delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Main.dfm delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Main.pas delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.cfg delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.dof delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.dpr delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.res delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/ID3v1.pas delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Info.txt delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Main.dfm delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Main.pas delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.cfg delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.dof delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.dpr delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.res delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/ID3v2.pas delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Info.txt delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Main.dfm delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Main.pas delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.cfg delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.dof delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.dpr delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.res delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Info.txt delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Main.dfm delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Main.pas delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Monkey.pas delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.cfg delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.dof delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.dpr delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.res delete mode 100644 MAC_SDK/3rd Party/TMonkey (Delphi)/Readme.txt delete mode 100644 MAC_SDK/Analyze/Sample 1/Sample 1.cpp delete mode 100644 MAC_SDK/Analyze/Sample 1/Sample 1.dsp delete mode 100644 MAC_SDK/Compress/Sample 1/Sample 1.cpp delete mode 100644 MAC_SDK/Compress/Sample 1/Sample 1.dsp delete mode 100644 MAC_SDK/Compress/Sample 2/Sample 2.cpp delete mode 100644 MAC_SDK/Compress/Sample 2/Sample 2.dsp delete mode 100644 MAC_SDK/Decompress/Sample 1/Sample 1.cpp delete mode 100644 MAC_SDK/Decompress/Sample 1/Sample 1.dsp delete mode 100644 MAC_SDK/Decompress/Sample 1/Sample 1.vcproj delete mode 100644 MAC_SDK/Decompress/Sample 2/Sample 2.cpp delete mode 100644 MAC_SDK/Decompress/Sample 2/Sample 2.dsp delete mode 100644 MAC_SDK/Decompress/Sample 2/Sample 2.vcproj delete mode 100644 MAC_SDK/Decompress/Sample 3/Sample 3.cpp delete mode 100644 MAC_SDK/Decompress/Sample 3/Sample 3.dsp delete mode 100644 MAC_SDK/Decompress/Sample 3/Sample 3.vcproj delete mode 100644 MAC_SDK/Shared/APETag.h delete mode 100644 MAC_SDK/Shared/All.h delete mode 100644 MAC_SDK/Shared/IO.h delete mode 100644 MAC_SDK/Shared/MACDll.h delete mode 100644 MAC_SDK/Shared/MACLib.h delete mode 100644 MAC_SDK/Shared/SmartPtr.h delete mode 100644 MAC_SDK/Source/Console/Console.cpp delete mode 100644 MAC_SDK/Source/Console/Console.dsp delete mode 100644 MAC_SDK/Source/Console/Console.vcproj delete mode 100644 MAC_SDK/Source/Console/Resource Script.rc delete mode 100644 MAC_SDK/Source/Console/resource.h delete mode 100644 MAC_SDK/Source/Credits.txt delete mode 100644 MAC_SDK/Source/History.txt delete mode 100644 MAC_SDK/Source/License.htm delete mode 100644 MAC_SDK/Source/MACDll/MACDll.cpp delete mode 100644 MAC_SDK/Source/MACDll/MACDll.def delete mode 100644 MAC_SDK/Source/MACDll/MACDll.dsp delete mode 100644 MAC_SDK/Source/MACDll/MACDll.h delete mode 100644 MAC_SDK/Source/MACDll/MACDll.vcproj delete mode 100644 MAC_SDK/Source/MACDll/Monkey Head (1).ico delete mode 100644 MAC_SDK/Source/MACDll/Monkey Head.ico delete mode 100644 MAC_SDK/Source/MACDll/Resource Script.rc delete mode 100644 MAC_SDK/Source/MACDll/resource.h delete mode 100644 MAC_SDK/Source/MACLib/APECompress.cpp delete mode 100644 MAC_SDK/Source/MACLib/APECompress.h delete mode 100644 MAC_SDK/Source/MACLib/APECompressCore.cpp delete mode 100644 MAC_SDK/Source/MACLib/APECompressCore.h delete mode 100644 MAC_SDK/Source/MACLib/APECompressCreate.cpp delete mode 100644 MAC_SDK/Source/MACLib/APECompressCreate.h delete mode 100644 MAC_SDK/Source/MACLib/APEDecompress.cpp delete mode 100644 MAC_SDK/Source/MACLib/APEDecompress.h delete mode 100644 MAC_SDK/Source/MACLib/APEHeader.cpp delete mode 100644 MAC_SDK/Source/MACLib/APEHeader.h delete mode 100644 MAC_SDK/Source/MACLib/APEInfo.cpp delete mode 100644 MAC_SDK/Source/MACLib/APEInfo.h delete mode 100644 MAC_SDK/Source/MACLib/APELink.cpp delete mode 100644 MAC_SDK/Source/MACLib/APELink.h delete mode 100644 MAC_SDK/Source/MACLib/APESimple.cpp delete mode 100644 MAC_SDK/Source/MACLib/APETag.cpp delete mode 100644 MAC_SDK/Source/MACLib/APETag.h delete mode 100644 MAC_SDK/Source/MACLib/Assembly/Assembly.h delete mode 100644 MAC_SDK/Source/MACLib/Assembly/Assembly.nas delete mode 100644 MAC_SDK/Source/MACLib/Assembly/Assembly.obj delete mode 100644 MAC_SDK/Source/MACLib/Assembly/Assembly64.nas delete mode 100644 MAC_SDK/Source/MACLib/Assembly/Assembly64.obj delete mode 100644 MAC_SDK/Source/MACLib/Assembly/Tools.inc delete mode 100644 MAC_SDK/Source/MACLib/Assembly/Tools64.inc delete mode 100644 MAC_SDK/Source/MACLib/BitArray.cpp delete mode 100644 MAC_SDK/Source/MACLib/BitArray.h delete mode 100644 MAC_SDK/Source/MACLib/MACLib.cpp delete mode 100644 MAC_SDK/Source/MACLib/MACLib.dsp delete mode 100644 MAC_SDK/Source/MACLib/MACLib.h delete mode 100644 MAC_SDK/Source/MACLib/MACLib.sln delete mode 100644 MAC_SDK/Source/MACLib/MACLib.vcproj delete mode 100644 MAC_SDK/Source/MACLib/MACLib.vcproj.7.10.old delete mode 100644 MAC_SDK/Source/MACLib/MACLib.vcxproj delete mode 100644 MAC_SDK/Source/MACLib/MACProgressHelper.cpp delete mode 100644 MAC_SDK/Source/MACLib/MACProgressHelper.h delete mode 100644 MAC_SDK/Source/MACLib/MD5.cpp delete mode 100644 MAC_SDK/Source/MACLib/MultichannelNNFilter.h delete mode 100644 MAC_SDK/Source/MACLib/NNFilter.cpp delete mode 100644 MAC_SDK/Source/MACLib/NNFilter.h delete mode 100644 MAC_SDK/Source/MACLib/NewPredictor.cpp delete mode 100644 MAC_SDK/Source/MACLib/NewPredictor.h delete mode 100644 MAC_SDK/Source/MACLib/Old/APEDecompressCore.cpp delete mode 100644 MAC_SDK/Source/MACLib/Old/APEDecompressCore.h delete mode 100644 MAC_SDK/Source/MACLib/Old/APEDecompressOld.cpp delete mode 100644 MAC_SDK/Source/MACLib/Old/APEDecompressOld.h delete mode 100644 MAC_SDK/Source/MACLib/Old/Anti-Predictor.cpp delete mode 100644 MAC_SDK/Source/MACLib/Old/Anti-Predictor.h delete mode 100644 MAC_SDK/Source/MACLib/Old/AntiPredictorExtraHigh.cpp delete mode 100644 MAC_SDK/Source/MACLib/Old/AntiPredictorFast.cpp delete mode 100644 MAC_SDK/Source/MACLib/Old/AntiPredictorHigh.cpp delete mode 100644 MAC_SDK/Source/MACLib/Old/AntiPredictorNormal.cpp delete mode 100644 MAC_SDK/Source/MACLib/Old/UnBitArrayOld.cpp delete mode 100644 MAC_SDK/Source/MACLib/Old/UnBitArrayOld.h delete mode 100644 MAC_SDK/Source/MACLib/Old/UnMAC.cpp delete mode 100644 MAC_SDK/Source/MACLib/Old/UnMAC.h delete mode 100644 MAC_SDK/Source/MACLib/Predictor.h delete mode 100644 MAC_SDK/Source/MACLib/Prepare.cpp delete mode 100644 MAC_SDK/Source/MACLib/Prepare.h delete mode 100644 MAC_SDK/Source/MACLib/ScaledFirstOrderFilter.h delete mode 100644 MAC_SDK/Source/MACLib/StartFilter.h delete mode 100644 MAC_SDK/Source/MACLib/UnBitArray.cpp delete mode 100644 MAC_SDK/Source/MACLib/UnBitArray.h delete mode 100644 MAC_SDK/Source/MACLib/UnBitArrayBase.cpp delete mode 100644 MAC_SDK/Source/MACLib/UnBitArrayBase.h delete mode 100644 MAC_SDK/Source/MACLib/WAVInputSource.cpp delete mode 100644 MAC_SDK/Source/MACLib/WAVInputSource.h delete mode 100644 MAC_SDK/Source/MACLib/md5.h delete mode 100644 MAC_SDK/Source/Makefile delete mode 100644 MAC_SDK/Source/Readme.htm delete mode 100644 MAC_SDK/Source/Shared/APEInfoDialog.cpp delete mode 100644 MAC_SDK/Source/Shared/APEInfoDialog.h delete mode 100644 MAC_SDK/Source/Shared/All.h delete mode 100644 MAC_SDK/Source/Shared/CharacterHelper.cpp delete mode 100644 MAC_SDK/Source/Shared/CharacterHelper.h delete mode 100644 MAC_SDK/Source/Shared/CircleBuffer.cpp delete mode 100644 MAC_SDK/Source/Shared/CircleBuffer.h delete mode 100644 MAC_SDK/Source/Shared/GlobalFunctions.cpp delete mode 100644 MAC_SDK/Source/Shared/GlobalFunctions.h delete mode 100644 MAC_SDK/Source/Shared/ID3Genres.h delete mode 100644 MAC_SDK/Source/Shared/IO.h delete mode 100644 MAC_SDK/Source/Shared/NoWindows.h delete mode 100644 MAC_SDK/Source/Shared/RollBuffer.h delete mode 100644 MAC_SDK/Source/Shared/SmartPtr.h delete mode 100644 MAC_SDK/Source/Shared/StdLibFileIO.cpp delete mode 100644 MAC_SDK/Source/Shared/StdLibFileIO.h delete mode 100644 MAC_SDK/Source/Shared/StdString.h delete mode 100644 MAC_SDK/Source/Shared/Unicows.cpp delete mode 100644 MAC_SDK/Source/Shared/WAVInfoDialog.cpp delete mode 100644 MAC_SDK/Source/Shared/WAVInfoDialog.h delete mode 100644 MAC_SDK/Source/Shared/WinFileIO.cpp delete mode 100644 MAC_SDK/Source/Shared/WinFileIO.h create mode 160000 ThirdParty/MAC_SDK create mode 100644 ThirdPartyDebug/x64/MACLib.lib create mode 100644 ThirdPartyDebug/x64/MACLib.pdb diff --git a/.gitignore b/.gitignore index 71d7b41..8152104 100644 --- a/.gitignore +++ b/.gitignore @@ -12,9 +12,5 @@ Debug/ a32/ launchSettings.json /CUETools/TestResults -/ThirdParty/x64/libFLAC_dynamic.pdb -/ThirdParty/x64/libFLAC_dynamic.lib -/ThirdParty/x64/libFLAC_dynamic.exp -/ThirdParty/Win32/libFLAC_dynamic.pdb -/ThirdParty/Win32/libFLAC_dynamic.lib -/ThirdParty/Win32/libFLAC_dynamic.exp +/ThirdParty/*/libFLAC_dynamic.* +/ThirdParty/*/MACLib.* diff --git a/.gitmodules b/.gitmodules index 0f42984..0cf6e48 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "ThirdParty/flac"] path = ThirdParty/flac url = https://github.com/gchudov/flac.git +[submodule "ThirdParty/MAC_SDK"] + path = ThirdParty/MAC_SDK + url = git@github.com:gchudov/MAC_SDK.git diff --git a/CUETools.Codecs.APE/CUETools.Codecs.APE.cpp b/CUETools.Codecs.APE/CUETools.Codecs.APE.cpp index 0a2e422..1b0fcf5 100644 --- a/CUETools.Codecs.APE/CUETools.Codecs.APE.cpp +++ b/CUETools.Codecs.APE/CUETools.Codecs.APE.cpp @@ -7,39 +7,18 @@ using namespace System::Runtime::InteropServices; using namespace System::IO; using namespace CUETools::Codecs; -#ifndef _WAVEFORMATEX_ -#define _WAVEFORMATEX_ - -#define BOOL int -#define TRUE 1 -#define FALSE 0 -#define HWND long - -/* - * extended waveform format structure used for all non-PCM formats. this - * structure is common to all non-PCM formats. - */ -typedef struct tWAVEFORMATEX -{ - Int16 wFormatTag; /* format type */ - Int16 nChannels; /* number of channels (i.e. mono, stereo...) */ - Int32 nSamplesPerSec; /* sample rate */ - Int32 nAvgBytesPerSec; /* for buffer estimation */ - Int16 nBlockAlign; /* block size of data */ - Int16 wBitsPerSample; /* number of bits per sample of mono data */ - Int16 cbSize; /* the count in bytes of the size of */ - /* extra information (after cbSize) */ -} WAVEFORMATEX, *PWAVEFORMATEX, *NPWAVEFORMATEX, *LPWAVEFORMATEX; - -#endif /* _WAVEFORMATEX_ */ - +#define PLATFORM_WINDOWS +#define PLATFORM_WINDOWS_NO_HEADER +#define EXCLUDE_CIO #include "All.h" #include "MACLib.h" #include "IO.h" +using namespace ::APE; + namespace CUETools { namespace Codecs { namespace APE { - class CWinFileIO : public CIO + class CWinFileIO : public ::APE::CIO { public: @@ -54,7 +33,7 @@ namespace CUETools { namespace Codecs { namespace APE { } // open / close - int Open(const wchar_t * pName) + int Open(const wchar_t * pName, bool bOpenReadOnly = false) { throw gcnew Exception("CIO::Open Unsupported."); } @@ -89,7 +68,7 @@ namespace CUETools { namespace Codecs { namespace APE { // attributes int GetPosition(); - int GetSize(); + unsigned int GetSize(); int GetName(wchar_t * pBuffer) { @@ -237,7 +216,7 @@ namespace CUETools { namespace Codecs { namespace APE { } private: - IAPEDecompress * pAPEDecompress; + ::APE::IAPEDecompress * pAPEDecompress; Int64 _sampleCount, _sampleOffset; AudioPCMConfig^ pcm; @@ -266,6 +245,14 @@ namespace CUETools { namespace Codecs { namespace APE { : AudioEncoderSettings("fast normal high extra insane", "high") { } + + virtual property String^ Version + { + String^ get() + { + return MAC_VERSION_STRING; + } + } }; [AudioEncoderClass("MAC_SDK", "ape", true, 1, APEWriterSettings::typeid)] @@ -377,7 +364,7 @@ namespace CUETools { namespace Codecs { namespace APE { private: IAPECompress * pAPECompress; bool _initialized; - Int32 _finalSampleCount, _samplesWritten; + Int64 _finalSampleCount, _samplesWritten; APEWriterSettings^ _settings; String^ _path; Stream^ _IO; @@ -445,7 +432,7 @@ namespace CUETools { namespace Codecs { namespace APE { return ((Stream^)_gchIO.Target)->Position; } - int CWinFileIO::GetSize() + unsigned int CWinFileIO::GetSize() { return ((Stream^)_gchIO.Target)->Length; } diff --git a/CUETools.Codecs.APE/CUETools.Codecs.APE.vcxproj b/CUETools.Codecs.APE/CUETools.Codecs.APE.vcxproj index 8e5ed85..79dd2c1 100644 --- a/CUETools.Codecs.APE/CUETools.Codecs.APE.vcxproj +++ b/CUETools.Codecs.APE/CUETools.Codecs.APE.vcxproj @@ -98,7 +98,7 @@ Disabled - ..\MAC_SDK\Shared;%(AdditionalIncludeDirectories) + ..\ThirdParty\MAC_SDK\Source\Shared;..\ThirdParty\MAC_SDK\Source\MACLib;%(AdditionalIncludeDirectories) WIN32;_DEBUG;%(PreprocessorDefinitions) MultiThreadedDebugDLL @@ -122,7 +122,7 @@ Disabled - ..\MAC_SDK\Shared;%(AdditionalIncludeDirectories) + ..\ThirdParty\MAC_SDK\Source\Shared;..\ThirdParty\MAC_SDK\Source\MACLib;%(AdditionalIncludeDirectories) WIN32;_DEBUG;%(PreprocessorDefinitions) MultiThreadedDebugDLL @@ -142,7 +142,7 @@ - ..\MAC_SDK\Shared;%(AdditionalIncludeDirectories) + ..\ThirdParty\MAC_SDK\Source\Shared;..\ThirdParty\MAC_SDK\Source\MACLib;%(AdditionalIncludeDirectories) WIN32;NDEBUG;%(PreprocessorDefinitions) MultiThreadedDLL @@ -157,6 +157,7 @@ MachineX86 + UseLinkTimeCodeGeneration @@ -164,7 +165,7 @@ X64 - ..\MAC_SDK\Shared;%(AdditionalIncludeDirectories) + ..\ThirdParty\MAC_SDK\Source\Shared;..\ThirdParty\MAC_SDK\Source\MACLib;%(AdditionalIncludeDirectories) WIN32;NDEBUG;%(PreprocessorDefinitions) MultiThreadedDLL @@ -179,6 +180,7 @@ MachineX64 + UseLinkTimeCodeGeneration @@ -225,9 +227,8 @@ true false - - {0b9c97d4-61b8-4294-a1df-ba90752a1779} - false + + {21bf980f-c022-4dcc-9250-7c73528e422b} diff --git a/CUETools.eac3to/Program.cs b/CUETools.eac3to/Program.cs index 498ec82..d812b8b 100644 --- a/CUETools.eac3to/Program.cs +++ b/CUETools.eac3to/Program.cs @@ -121,55 +121,63 @@ namespace CUETools.eac3to try #endif { - MPLSReader audioSource = null; + IAudioSource audioSource = null; IAudioDest audioDest = null; + var videos = new List(); + var audios = new List(); + List chapters; + TimeSpan duration; TagLib.UserDefined.AdditionalFileTypes.Config = config; try { - audioSource = new MPLSReader(sourceFile, null); - Console.ForegroundColor = ConsoleColor.White; - int frameRate = 0; - bool interlaced = false; - var chapters = audioSource.Chapters; - var videos = new List(); - var audios = new List(); - audioSource.MPLSHeader.play_item.ForEach(i => i.video.ForEach(v => { if (!videos.Exists(v1 => v1.pid == v.pid)) videos.Add(v); })); - audioSource.MPLSHeader.play_item.ForEach(i => i.audio.ForEach(v => { if (!audios.Exists(v1 => v1.pid == v.pid)) audios.Add(v); })); - videos.ForEach(v => { frameRate = v.FrameRate; interlaced = v.Interlaced; }); - Console.Error.WriteLine("M2TS, {0} video track{1}, {2} audio track{3}, {4}, {5}{6}", - videos.Count, videos.Count > 1 ? "s" : "", - audios.Count, audios.Count > 1 ? "s" : "", - CDImageLayout.TimeToString(audioSource.Duration, "{0:0}:{1:00}:{2:00}"), frameRate * (interlaced ? 2 : 1), interlaced ? "i" : "p"); - //foreach (var item in audioSource.MPLSHeader.play_item) - //Console.Error.WriteLine("{0}.m2ts", item.clip_id); + if (true) { - Console.ForegroundColor = ConsoleColor.Gray; - int id = 1; - if (chapters.Count > 1) + var mpls = new MPLSReader(sourceFile, null); + audioSource = mpls; + Console.ForegroundColor = ConsoleColor.White; + int frameRate = 0; + bool interlaced = false; + chapters = mpls.Chapters; + mpls.MPLSHeader.play_item.ForEach(i => i.video.ForEach(v => { if (!videos.Exists(v1 => v1.pid == v.pid)) videos.Add(v); })); + mpls.MPLSHeader.play_item.ForEach(i => i.audio.ForEach(v => { if (!audios.Exists(v1 => v1.pid == v.pid)) audios.Add(v); })); + videos.ForEach(v => { frameRate = v.FrameRate; interlaced = v.Interlaced; }); + Console.Error.WriteLine("M2TS, {0} video track{1}, {2} audio track{3}, {4}, {5}{6}", + videos.Count, videos.Count > 1 ? "s" : "", + audios.Count, audios.Count > 1 ? "s" : "", + CDImageLayout.TimeToString(mpls.Duration, "{0:0}:{1:00}:{2:00}"), frameRate * (interlaced ? 2 : 1), interlaced ? "i" : "p"); + //foreach (var item in mpls.MPLSHeader.play_item) + //Console.Error.WriteLine("{0}.m2ts", item.clip_id); { - Console.ForegroundColor = ConsoleColor.White; - Console.Error.Write(id++); - Console.Error.Write(": "); Console.ForegroundColor = ConsoleColor.Gray; - Console.Error.WriteLine("Chapters, {0} chapters", chapters.Count - 1); - } - foreach (var video in videos) - { - Console.ForegroundColor = ConsoleColor.White; - Console.Error.Write(id++); - Console.Error.Write(": "); - Console.ForegroundColor = ConsoleColor.Gray; - Console.Error.WriteLine("{0}, {1}{2}", video.CodecString, video.FormatString, video.FrameRate * (video.Interlaced ? 2 : 1)); - } - foreach (var audio in audios) - { - Console.ForegroundColor = ConsoleColor.White; - Console.Error.Write(id++); - Console.Error.Write(": "); - Console.ForegroundColor = ConsoleColor.Gray; - Console.Error.WriteLine("{0}, {1}, {2}, {3}", audio.CodecString, audio.LanguageString, audio.FormatString, audio.RateString); + int id = 1; + if (chapters.Count > 1) + { + Console.ForegroundColor = ConsoleColor.White; + Console.Error.Write(id++); + Console.Error.Write(": "); + Console.ForegroundColor = ConsoleColor.Gray; + Console.Error.WriteLine("Chapters, {0} chapters", chapters.Count - 1); + } + foreach (var video in videos) + { + Console.ForegroundColor = ConsoleColor.White; + Console.Error.Write(id++); + Console.Error.Write(": "); + Console.ForegroundColor = ConsoleColor.Gray; + Console.Error.WriteLine("{0}, {1}{2}", video.CodecString, video.FormatString, video.FrameRate * (video.Interlaced ? 2 : 1)); + } + foreach (var audio in audios) + { + Console.ForegroundColor = ConsoleColor.White; + Console.Error.Write(id++); + Console.Error.Write(": "); + Console.ForegroundColor = ConsoleColor.Gray; + Console.Error.WriteLine("{0}, {1}, {2}, {3}", audio.CodecString, audio.LanguageString, audio.FormatString, audio.RateString); + } } + + duration = mpls.Duration; } if (destFile == null) @@ -299,18 +307,21 @@ namespace CUETools.eac3to throw new Exception("Unknown encoder format: " + destFile); } - if (stream - chapterStreams <= videos.Count) - throw new Exception("Video extraction not supported."); - if (stream - chapterStreams - videos.Count > audios.Count) - throw new Exception(string.Format("The source file doesn't contain a track with the number {0}.", stream)); - ushort pid = audios[stream - chapterStreams - videos.Count - 1].pid; - (audioSource.Settings as BDLPCMReaderSettings).Pid = pid; + if (audioSource is MPLSReader) + { + if (stream - chapterStreams <= videos.Count) + throw new Exception("Video extraction not supported."); + if (stream - chapterStreams - videos.Count > audios.Count) + throw new Exception(string.Format("The source file doesn't contain a track with the number {0}.", stream)); + ushort pid = audios[stream - chapterStreams - videos.Count - 1].pid; + (audioSource.Settings as BDLPCMReaderSettings).Pid = pid; + } } AudioBuffer buff = new AudioBuffer(audioSource, 0x10000); Console.Error.WriteLine("Filename : {0}", sourceFile); Console.Error.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.PCM.SampleRate, audioSource.PCM.ChannelCount, audioSource.PCM.BitsPerSample, - audioSource.Duration); + duration); CUEToolsFormat fmt; if (encoderFormat == null) @@ -384,7 +395,7 @@ namespace CUETools.eac3to TimeSpan elapsed = DateTime.Now - start; if ((elapsed - lastPrint).TotalMilliseconds > 60) { - long length = (long)(audioSource.Duration.TotalSeconds * audioSource.PCM.SampleRate); + long length = (long)(duration.TotalSeconds * audioSource.PCM.SampleRate); if (length < audioSource.Position) length = audioSource.Position; if (length < 1) length = 1; Console.Error.Write("\rProgress : {0:00}%; {1:0.00}x; {2}/{3}", diff --git a/CUETools/CUETools.sln b/CUETools/CUETools.sln index 9f8c0d3..928767d 100644 --- a/CUETools/CUETools.sln +++ b/CUETools/CUETools.sln @@ -60,8 +60,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CUETools.Codecs.APE", "..\C EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CUETools.Codecs.WavPack", "..\CUETools.Codecs.WavPack\CUETools.Codecs.WavPack.vcxproj", "{CC2E74B6-534A-43D8-9F16-AC03FE955000}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MACLib", "..\MAC_SDK\Source\MACLib\MACLib.vcxproj", "{0B9C97D4-61B8-4294-A1DF-BA90752A1779}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwavpack", "..\wavpack-4.5.0\src\libwavpack.vcxproj", "{5CCCB9CF-0384-458F-BA08-72B73866840F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CUETools.ARCUE", "..\CUETools.ARCUE\CUETools.ARCUE.csproj", "{A5A8D8FA-9E32-4010-8AAF-AE580C5AF728}" @@ -192,6 +190,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "taglib-sharp", "..\ThirdPar EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libFLAC_dynamic", "..\ThirdParty\flac\src\libFLAC\libFLAC_dynamic.vcxproj", "{4CEFBC83-C215-11DB-8314-0800200C9A66}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MACLib", "..\ThirdParty\MAC_SDK\Source\Projects\VS2017\MACLib\MACLib.vcxproj", "{21BF980F-C022-4DCC-9250-7C73528E422B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -252,22 +252,6 @@ Global {CC2E74B6-534A-43D8-9F16-AC03FE955000}.Release|x64.ActiveCfg = Release|x64 {CC2E74B6-534A-43D8-9F16-AC03FE955000}.Release|x64.Build.0 = Release|x64 {CC2E74B6-534A-43D8-9F16-AC03FE955000}.Release|x86.ActiveCfg = Release|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|Any CPU.ActiveCfg = Debug|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|Mixed Platforms.Build.0 = Debug|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|Win32.ActiveCfg = Debug|Win32 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|Win32.Build.0 = Debug|Win32 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|x64.ActiveCfg = Debug|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|x64.Build.0 = Debug|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|x86.ActiveCfg = Debug|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|Any CPU.ActiveCfg = Release|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|Mixed Platforms.ActiveCfg = Release|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|Mixed Platforms.Build.0 = Release|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|Win32.ActiveCfg = Release|Win32 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|Win32.Build.0 = Release|Win32 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|x64.ActiveCfg = Release|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|x64.Build.0 = Release|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|x86.ActiveCfg = Release|x64 {5CCCB9CF-0384-458F-BA08-72B73866840F}.Debug|Any CPU.ActiveCfg = Debug|x64 {5CCCB9CF-0384-458F-BA08-72B73866840F}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 {5CCCB9CF-0384-458F-BA08-72B73866840F}.Debug|Mixed Platforms.Build.0 = Debug|x64 @@ -1140,6 +1124,24 @@ Global {4CEFBC83-C215-11DB-8314-0800200C9A66}.Release|x64.Build.0 = Release|x64 {4CEFBC83-C215-11DB-8314-0800200C9A66}.Release|x86.ActiveCfg = Release|Win32 {4CEFBC83-C215-11DB-8314-0800200C9A66}.Release|x86.Build.0 = Release|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Debug|Win32.ActiveCfg = Debug|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Debug|Win32.Build.0 = Debug|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Debug|x64.ActiveCfg = Debug|x64 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Debug|x64.Build.0 = Debug|x64 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Debug|x86.ActiveCfg = Debug|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Debug|x86.Build.0 = Debug|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Release|Any CPU.ActiveCfg = Release|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Release|Mixed Platforms.Build.0 = Release|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Release|Win32.ActiveCfg = Release|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Release|Win32.Build.0 = Release|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Release|x64.ActiveCfg = Release|x64 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Release|x64.Build.0 = Release|x64 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Release|x86.ActiveCfg = Release|Win32 + {21BF980F-C022-4DCC-9250-7C73528E422B}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1154,7 +1156,6 @@ Global {0E404B8B-FF82-427F-ADE4-77B54A29219F} = {5D823ABE-D280-4800-824C-2633CBAB2EA9} {9AE965C4-301E-4C01-B90F-297AF341ACC6} = {39A17A65-E893-44B8-A312-DDCDD990D9D1} {CC2E74B6-534A-43D8-9F16-AC03FE955000} = {39A17A65-E893-44B8-A312-DDCDD990D9D1} - {0B9C97D4-61B8-4294-A1DF-BA90752A1779} = {8B179853-B7D6-479C-B8B2-6CBCE835D040} {5CCCB9CF-0384-458F-BA08-72B73866840F} = {8B179853-B7D6-479C-B8B2-6CBCE835D040} {A5A8D8FA-9E32-4010-8AAF-AE580C5AF728} = {4B59E09C-A51F-4B80-91BE-987904DCEF7D} {32338A04-5B6B-4C63-8EE7-C6400F73B5D7} = {FD0D49DB-8F02-4A64-A9A3-A5AF54481770} @@ -1198,6 +1199,7 @@ Global {F10AB92C-9AFB-4FC0-94E0-06FCD3CA8155} = {93B7AE1D-DEF6-4A04-A222-5CDE09DF262D} {1219A514-D3FA-40DB-BBB2-92CE05E35839} = {7E402406-7E51-4F0D-8209-60824C1CD6E8} {4CEFBC83-C215-11DB-8314-0800200C9A66} = {7E402406-7E51-4F0D-8209-60824C1CD6E8} + {21BF980F-C022-4DCC-9250-7C73528E422B} = {8B179853-B7D6-479C-B8B2-6CBCE835D040} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C634D169-5814-4203-94B6-6A11371DDA95} diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/APEtag.pas b/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/APEtag.pas deleted file mode 100644 index 3751574..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/APEtag.pas +++ /dev/null @@ -1,488 +0,0 @@ -{ *************************************************************************** } -{ } -{ Audio Tools Library (Freeware) } -{ Class TAPEtag - for manipulating with APE tags } -{ } -{ Copyright (c) 2001,2002 by Jurgen Faul } -{ E-mail: jfaul@gmx.de } -{ http://jfaul.de/atl } -{ } -{ Version 1.0 (21 April 2002) } -{ - Reading & writing support for APE 1.0 tags } -{ - Reading support for APE 2.0 tags (UTF-8 decoding) } -{ - Tag info: title, artist, album, track, year, genre, comment, copyright } -{ } -{ *************************************************************************** } - -unit APEtag; - -interface - -uses - Classes, SysUtils; - -type - { Class TAPEtag } - TAPEtag = class(TObject) - private - { Private declarations } - FExists: Boolean; - FVersion: Integer; - FSize: Integer; - FTitle: string; - FArtist: string; - FAlbum: string; - FTrack: Byte; - FYear: string; - FGenre: string; - FComment: string; - FCopyright: string; - procedure FSetTitle(const NewTitle: string); - procedure FSetArtist(const NewArtist: string); - procedure FSetAlbum(const NewAlbum: string); - procedure FSetTrack(const NewTrack: Byte); - procedure FSetYear(const NewYear: string); - procedure FSetGenre(const NewGenre: string); - procedure FSetComment(const NewComment: string); - procedure FSetCopyright(const NewCopyright: string); - public - { Public declarations } - constructor Create; { Create object } - procedure ResetData; { Reset all data } - function ReadFromFile(const FileName: string): Boolean; { Load tag } - function RemoveFromFile(const FileName: string): Boolean; { Delete tag } - function SaveToFile(const FileName: string): Boolean; { Save tag } - property Exists: Boolean read FExists; { True if tag found } - property Version: Integer read FVersion; { Tag version } - property Size: Integer read FSize; { Total tag size } - property Title: string read FTitle write FSetTitle; { Song title } - property Artist: string read FArtist write FSetArtist; { Artist name } - property Album: string read FAlbum write FSetAlbum; { Album title } - property Track: Byte read FTrack write FSetTrack; { Track number } - property Year: string read FYear write FSetYear; { Release year } - property Genre: string read FGenre write FSetGenre; { Genre name } - property Comment: string read FComment write FSetComment; { Comment } - property Copyright: string read FCopyright write FSetCopyright; { (c) } - end; - -implementation - -const - { Tag ID } - ID3V1_ID = 'TAG'; { ID3v1 } - APE_ID = 'APETAGEX'; { APE } - - { Size constants } - ID3V1_TAG_SIZE = 128; { ID3v1 tag } - APE_TAG_FOOTER_SIZE = 32; { APE tag footer } - APE_TAG_HEADER_SIZE = 32; { APE tag header } - - { First version of APE tag } - APE_VERSION_1_0 = 1000; - - { Max. number of supported tag fields } - APE_FIELD_COUNT = 8; - - { Names of supported tag fields } - APE_FIELD: array [1..APE_FIELD_COUNT] of string = - ('Title', 'Artist', 'Album', 'Track', 'Year', 'Genre', - 'Comment', 'Copyright'); - -type - { APE tag data - for internal use } - TagInfo = record - { Real structure of APE footer } - ID: array [1..8] of Char; { Always "APETAGEX" } - Version: Integer; { Tag version } - Size: Integer; { Tag size including footer } - Fields: Integer; { Number of fields } - Flags: Integer; { Tag flags } - Reserved: array [1..8] of Char; { Reserved for later use } - { Extended data } - DataShift: Byte; { Used if ID3v1 tag found } - FileSize: Integer; { File size (bytes) } - Field: array [1..APE_FIELD_COUNT] of string; { Information from fields } - end; - -{ ********************* Auxiliary functions & procedures ******************** } - -function ReadFooter(const FileName: string; var Tag: TagInfo): Boolean; -var - SourceFile: file; - TagID: array [1..3] of Char; - Transferred: Integer; -begin - { Load footer from file to variable } - try - Result := true; - { Set read-access and open file } - AssignFile(SourceFile, FileName); - FileMode := 0; - Reset(SourceFile, 1); - Tag.FileSize := FileSize(SourceFile); - { Check for existing ID3v1 tag } - Seek(SourceFile, Tag.FileSize - ID3V1_TAG_SIZE); - BlockRead(SourceFile, TagID, SizeOf(TagID)); - if TagID = ID3V1_ID then Tag.DataShift := ID3V1_TAG_SIZE; - { Read footer data } - Seek(SourceFile, Tag.FileSize - Tag.DataShift - APE_TAG_FOOTER_SIZE); - BlockRead(SourceFile, Tag, APE_TAG_FOOTER_SIZE, Transferred); - CloseFile(SourceFile); - { if transfer is not complete } - if Transferred < APE_TAG_FOOTER_SIZE then Result := false; - except - { Error } - Result := false; - end; -end; - -{ --------------------------------------------------------------------------- } - -function ConvertFromUTF8(const Source: string): string; -var - Iterator, SourceLength, FChar, NChar: Integer; -begin - { Convert UTF-8 string to ANSI string } - Result := ''; - Iterator := 0; - SourceLength := Length(Source); - while Iterator < SourceLength do - begin - Inc(Iterator); - FChar := Ord(Source[Iterator]); - if FChar >= $80 then - begin - Inc(Iterator); - if Iterator > SourceLength then break; - FChar := FChar and $3F; - if (FChar and $20) <> 0 then - begin - FChar := FChar and $1F; - NChar := Ord(Source[Iterator]); - if (NChar and $C0) <> $80 then break; - FChar := (FChar shl 6) or (NChar and $3F); - Inc(Iterator); - if Iterator > SourceLength then break; - end; - NChar := Ord(Source[Iterator]); - if (NChar and $C0) <> $80 then break; - Result := Result + WideChar((FChar shl 6) or (NChar and $3F)); - end - else - Result := Result + WideChar(FChar); - end; -end; - -{ --------------------------------------------------------------------------- } - -procedure SetTagItem(const FieldName, FieldValue: string; var Tag: TagInfo); -var - Iterator: Byte; -begin - { Set tag item if supported field found } - for Iterator := 1 to APE_FIELD_COUNT do - if UpperCase(FieldName) = UpperCase(APE_FIELD[Iterator]) then - if Tag.Version > APE_VERSION_1_0 then - Tag.Field[Iterator] := ConvertFromUTF8(FieldValue) - else - Tag.Field[Iterator] := FieldValue; -end; - -{ --------------------------------------------------------------------------- } - -procedure ReadFields(const FileName: string; var Tag: TagInfo); -var - SourceFile: file; - FieldName: string; - FieldValue: array [1..250] of Char; - NextChar: Char; - Iterator, ValueSize, ValuePosition, FieldFlags: Integer; -begin - try - { Set read-access, open file } - AssignFile(SourceFile, FileName); - FileMode := 0; - Reset(SourceFile, 1); - Seek(SourceFile, Tag.FileSize - Tag.DataShift - Tag.Size); - { Read all stored fields } - for Iterator := 1 to Tag.Fields do - begin - FillChar(FieldValue, SizeOf(FieldValue), 0); - BlockRead(SourceFile, ValueSize, SizeOf(ValueSize)); - BlockRead(SourceFile, FieldFlags, SizeOf(FieldFlags)); - FieldName := ''; - repeat - BlockRead(SourceFile, NextChar, SizeOf(NextChar)); - FieldName := FieldName + NextChar; - until Ord(NextChar) = 0; - ValuePosition := FilePos(SourceFile); - BlockRead(SourceFile, FieldValue, ValueSize mod SizeOf(FieldValue)); - SetTagItem(Trim(FieldName), Trim(FieldValue), Tag); - Seek(SourceFile, ValuePosition + ValueSize); - end; - CloseFile(SourceFile); - except - end; -end; - -{ --------------------------------------------------------------------------- } - -function GetTrack(const TrackString: string): Byte; -var - Index, Value, Code: Integer; -begin - { Get track from string } - Index := Pos('/', TrackString); - if Index = 0 then Val(TrackString, Value, Code) - else Val(Copy(TrackString, 1, Index - 1), Value, Code); - if Code = 0 then Result := Value - else Result := 0; -end; - -{ --------------------------------------------------------------------------- } - -function TruncateFile(const FileName: string; TagSize: Integer): Boolean; -var - SourceFile: file; -begin - try - Result := true; - { Allow write-access and open file } - FileSetAttr(FileName, 0); - AssignFile(SourceFile, FileName); - FileMode := 2; - Reset(SourceFile, 1); - { Delete tag } - Seek(SourceFile, FileSize(SourceFile) - TagSize); - Truncate(SourceFile); - CloseFile(SourceFile); - except - { Error } - Result := false; - end; -end; - -{ --------------------------------------------------------------------------- } - -procedure BuildFooter(var Tag: TagInfo); -var - Iterator: Integer; -begin - { Build tag footer } - Tag.ID := APE_ID; - Tag.Version := APE_VERSION_1_0; - Tag.Size := APE_TAG_FOOTER_SIZE; - for Iterator := 1 to APE_FIELD_COUNT do - if Tag.Field[Iterator] <> '' then - begin - Inc(Tag.Size, Length(APE_FIELD[Iterator] + Tag.Field[Iterator]) + 10); - Inc(Tag.Fields); - end; -end; - -{ --------------------------------------------------------------------------- } - -function AddToFile(const FileName: string; TagData: TStream): Boolean; -var - FileData: TFileStream; -begin - try - { Add tag data to file } - FileData := TFileStream.Create(FileName, fmOpenWrite or fmShareExclusive); - FileData.Seek(0, soFromEnd); - TagData.Seek(0, soFromBeginning); - FileData.CopyFrom(TagData, TagData.Size); - FileData.Free; - Result := true; - except - { Error } - Result := false; - end; -end; - -{ --------------------------------------------------------------------------- } - -function SaveTag(const FileName: string; Tag: TagInfo): Boolean; -var - TagData: TStringStream; - Iterator, ValueSize, Flags: Integer; -begin - { Build and write tag fields and footer to stream } - TagData := TStringStream.Create(''); - for Iterator := 1 to APE_FIELD_COUNT do - if Tag.Field[Iterator] <> '' then - begin - ValueSize := Length(Tag.Field[Iterator]) + 1; - Flags := 0; - TagData.Write(ValueSize, SizeOf(ValueSize)); - TagData.Write(Flags, SizeOf(Flags)); - TagData.WriteString(APE_FIELD[Iterator] + #0); - TagData.WriteString(Tag.Field[Iterator] + #0); - end; - BuildFooter(Tag); - TagData.Write(Tag, APE_TAG_FOOTER_SIZE); - { Add created tag to file } - Result := AddToFile(FileName, TagData); - TagData.Free; -end; - -{ ********************** Private functions & procedures ********************* } - -procedure TAPEtag.FSetTitle(const NewTitle: string); -begin - { Set song title } - FTitle := Trim(NewTitle); -end; - -{ --------------------------------------------------------------------------- } - -procedure TAPEtag.FSetArtist(const NewArtist: string); -begin - { Set artist name } - FArtist := Trim(NewArtist); -end; - -{ --------------------------------------------------------------------------- } - -procedure TAPEtag.FSetAlbum(const NewAlbum: string); -begin - { Set album title } - FAlbum := Trim(NewAlbum); -end; - -{ --------------------------------------------------------------------------- } - -procedure TAPEtag.FSetTrack(const NewTrack: Byte); -begin - { Set track number } - FTrack := NewTrack; -end; - -{ --------------------------------------------------------------------------- } - -procedure TAPEtag.FSetYear(const NewYear: string); -begin - { Set release year } - FYear := Trim(NewYear); -end; - -{ --------------------------------------------------------------------------- } - -procedure TAPEtag.FSetGenre(const NewGenre: string); -begin - { Set genre name } - FGenre := Trim(NewGenre); -end; - -{ --------------------------------------------------------------------------- } - -procedure TAPEtag.FSetComment(const NewComment: string); -begin - { Set comment } - FComment := Trim(NewComment); -end; - -{ --------------------------------------------------------------------------- } - -procedure TAPEtag.FSetCopyright(const NewCopyright: string); -begin - { Set copyright information } - FCopyright := Trim(NewCopyright); -end; - -{ ********************** Public functions & procedures ********************** } - -constructor TAPEtag.Create; -begin - { Create object } - inherited; - ResetData; -end; - -{ --------------------------------------------------------------------------- } - -procedure TAPEtag.ResetData; -begin - { Reset all variables } - FExists := false; - FVersion := 0; - FSize := 0; - FTitle := ''; - FArtist := ''; - FAlbum := ''; - FTrack := 0; - FYear := ''; - FGenre := ''; - FComment := ''; - FCopyright := ''; -end; - -{ --------------------------------------------------------------------------- } - -function TAPEtag.ReadFromFile(const FileName: string): Boolean; -var - Tag: TagInfo; -begin - { Reset data and load footer from file to variable } - ResetData; - FillChar(Tag, SizeOf(Tag), 0); - Result := ReadFooter(FileName, Tag); - { Process data if loaded and footer valid } - if (Result) and (Tag.ID = APE_ID) then - begin - FExists := true; - { Fill properties with footer data } - FVersion := Tag.Version; - FSize := Tag.Size; - { Get information from fields } - ReadFields(FileName, Tag); - FTitle := Tag.Field[1]; - FArtist := Tag.Field[2]; - FAlbum := Tag.Field[3]; - FTrack := GetTrack(Tag.Field[4]); - FYear := Tag.Field[5]; - FGenre := Tag.Field[6]; - FComment := Tag.Field[7]; - FCopyright := Tag.Field[8]; - end; -end; - -{ --------------------------------------------------------------------------- } - -function TAPEtag.RemoveFromFile(const FileName: string): Boolean; -var - Tag: TagInfo; -begin - { Remove tag from file if found } - FillChar(Tag, SizeOf(Tag), 0); - if ReadFooter(FileName, Tag) then - begin - if Tag.ID <> APE_ID then Tag.Size := 0; - if (Tag.Flags shr 31) > 0 then Inc(Tag.Size, APE_TAG_HEADER_SIZE); - Result := TruncateFile(FileName, Tag.DataShift + Tag.Size) - end - else - Result := false; -end; - -{ --------------------------------------------------------------------------- } - -function TAPEtag.SaveToFile(const FileName: string): Boolean; -var - Tag: TagInfo; -begin - { Prepare tag data and save to file } - FillChar(Tag, SizeOf(Tag), 0); - Tag.Field[1] := FTitle; - Tag.Field[2] := FArtist; - Tag.Field[3] := FAlbum; - if FTrack > 0 then Tag.Field[4] := IntToStr(FTrack); - Tag.Field[5] := FYear; - Tag.Field[6] := FGenre; - Tag.Field[7] := FComment; - Tag.Field[8] := FCopyright; - { Delete old tag if exists and write new tag } - Result := (RemoveFromFile(FileName)) and (SaveTag(FileName, Tag)); -end; - -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Info.txt b/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Info.txt deleted file mode 100644 index f649184..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Info.txt +++ /dev/null @@ -1,18 +0,0 @@ -APEtag.pas -Tested with Borland Delphi 3,4,5,6 - -{ *************************************************************************** } -{ } -{ Audio Tools Library (Freeware) } -{ Class TAPEtag - for manipulating with APE tags } -{ } -{ Copyright (c) 2001,2002 by Jurgen Faul } -{ E-mail: jfaul@gmx.de } -{ http://jfaul.de/atl } -{ } -{ Version 1.0 (21 April 2002) } -{ - Reading & writing support for APE 1.0 tags } -{ - Reading support for APE 2.0 tags (UTF-8 decoding) } -{ - Tag info: title, artist, album, track, year, genre, comment, copyright } -{ } -{ *************************************************************************** } \ No newline at end of file diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Main.dfm b/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Main.dfm deleted file mode 100644 index e9fccb021c00ee2f0e18d897a9fbdb0ed860e923..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5596 zcmey*#Sr4_=;`O?ALPqmAaGKYfgvQo&44q+H!(BMEx#z21IA$SNlhzZR%K)k$uD5; zW#Dy8F3BuQb(gdpHIKyM}N*$%OG=AU^;{B561k3WFfg!&fQ(^aU}RuqP*4ET z91JTs7#PGD7#K7d7#I{77#JKFAmR)lzyczmm=P=ic}nsHtIKm_3_;Vb?AOhMPAT7(RSpQ2GC#!Q=mbhMfQZ87BPy&#>h` zNWB&VL##amLrn++!|Y53hFx_G3^yk;Fnn0Wpz?nkgUA0v3_1VLF--V>i($+EXABH> zA`A?%atsVL8Vn4xjTjhq*)TBNbYo!n5XzwPKbOJde=9@I|G5kk{%>X2^8YNp;9*et zufpK*--99Ne-6Wh{}ULt{NI8vco=g3t1z_w_h6X&KZjxK{|O9d|8Kz;JPh0Zt1uk; z@4;~He-6W~{}ULV{ojHwco_cwS7G@7--F@*{~U(@|0gi~2dT#$JPiN0sWALM)(H&%&u+n!dKeh~tEe#i_wZo&pOeGz zf5HTY|64%nMHpfk=}@47(WI7;Z9zGJIgjRr$}*>hYgpZq9#(trPw;oZa%DfsKug zK}bl5L0(>-K}Sc2!P3%_!PV83At)$_AwE8yAtxt?p`xOKp|!P@VbY{Y4D;vDXIQ;@ zHN%b_I~a~0J<4$D(j|s__wF&ge*K!^$B!QjAAbL5Sh8RNLqh{7WB+Gh_|L$=@c%!A zV)zeYGW-YS3up;IJoW6|)2C10yuqd6+0&}q|K7b+e2Fao6y5rlid;zYXu25~UcOX(3YLHQOzGLPr>KTAFfhD) z2Dbn0+h_Og-Ft>+I7I&C8^yOzpFVwd?-{z~Ao-^t_q}}i?c2*|-@c*gfA{j;)3=IG zpDI54_U+rZr~kj9h0QZ1ZY6NwK;*xn%D?1NQ&Usp0x5XRj)RdnpDn5OtsK}+Hri5faIP_jV zd&;Gz%=Ju(>*>p9Ptm;q^6tB5V1KHqJwppUkR%vCg9H?c)nExI@$B6*u4hki>1JSH zc=rAoTB`gH1_$c@|8KDW|DQqr|33!)|9=?x|NnsE2MqlG4O?yFxZ3e4+aK%5dOo!VE>PSq5l5^=KueHu>b%6ga7~k zKlcAYO(LJfq|_X~ki>M?ip=7YVlWrnE@DyuH;XPXK-yAFj<9BtAiP<`foPwGB&I8* zf=#eu^GU4CFD+r`D9Le7%_~VQf?LBAmReMtnV*NSgn0u4sx5~2Y~g_F$72O2sJVt@ zz5%3#4)=v6KJ!^Yn(-LU6_Qz!lZr4M8bmLM3L-YJW;~{II~J8>7MEZc&%j7b46s9V z<1wGhF(;`s7sGf7qKsz)YsP1KNKs;PHiqd2#F-A(jK_4&$kfClgyFDc12-LSvS9^j z#$z~_dum=0QnWHd6Aj#SyorVltQ(Kp>`4yaCo=;|R38b6=_qmt^Ac>UuBm*pm3A4Lo z7J-z3dUZJ|sbDroNMaJWZ^*>J5t3R_;+$BV%FbPq99mG2S_I-SFbIaYWEQ0+m*f{! zf^<9OS8%!I!}KFtX@G7eb0-6bTV_rwNEo-HjtOaH?cUIjay4Eu^`o2OE0$|8DRwzsAHRvn3tZ)&Ihx} z8OU=M)~4}g2X5H`eS0Z4ze02Xt>umF{0b56`lPR-$j7rU%r%?Jwxz@6*N)mVk?HQ0O5C7p&N4?u4ZcCQ(Q*adP@5R`{gmrI%zd|6)K5GkE%EgPG0+DY?;& zhZXx|8qW?ho)cVhqni#Z^~p3HJOBbRlM`HWgILHx11~w@QA|q6aKfC<0V=rRX2a4C zWrlOX4Ce%w+X&O4DFH~;_u diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Main.pas b/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Main.pas deleted file mode 100644 index 2547c3f..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Main.pas +++ /dev/null @@ -1,159 +0,0 @@ -unit Main; - -interface - -uses - Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - StdCtrls, FileCtrl, ExtCtrls, APEtag; - -type - TMainForm = class(TForm) - DriveList: TDriveComboBox; - FolderList: TDirectoryListBox; - FileList: TFileListBox; - SaveButton: TButton; - RemoveButton: TButton; - CloseButton: TButton; - InfoBevel: TBevel; - IconImage: TImage; - TagExistsLabel: TLabel; - TagExistsValue: TEdit; - VersionLabel: TLabel; - VersionValue: TEdit; - SizeLabel: TLabel; - SizeValue: TEdit; - TitleLabel: TLabel; - TitleEdit: TEdit; - ArtistLabel: TLabel; - ArtistEdit: TEdit; - AlbumLabel: TLabel; - AlbumEdit: TEdit; - TrackLabel: TLabel; - TrackEdit: TEdit; - YearLabel: TLabel; - YearEdit: TEdit; - GenreLabel: TLabel; - GenreEdit: TEdit; - CommentLabel: TLabel; - CommentEdit: TEdit; - CopyrightLabel: TLabel; - CopyrightEdit: TEdit; - procedure FormCreate(Sender: TObject); - procedure FileListChange(Sender: TObject); - procedure FormClose(Sender: TObject; var Action: TCloseAction); - procedure SaveButtonClick(Sender: TObject); - procedure RemoveButtonClick(Sender: TObject); - procedure CloseButtonClick(Sender: TObject); - private - { Private declarations } - FileTag: TAPEtag; - procedure ClearAll; - end; - -var - MainForm: TMainForm; - -implementation - -{$R *.dfm} - -procedure TMainForm.ClearAll; -begin - { Clear all captions } - TagExistsValue.Text := ''; - VersionValue.Text := ''; - SizeValue.Text := ''; - TitleEdit.Text := ''; - ArtistEdit.Text := ''; - AlbumEdit.Text := ''; - TrackEdit.Text := ''; - YearEdit.Text := ''; - GenreEdit.Text := ''; - CommentEdit.Text := ''; - CopyrightEdit.Text := ''; -end; - -procedure TMainForm.FormCreate(Sender: TObject); -begin - { Create object and clear captions } - FileTag := TAPEtag.Create; - ClearAll; -end; - -procedure TMainForm.FileListChange(Sender: TObject); -begin - { Clear captions } - ClearAll; - if FileList.FileName = '' then exit; - if FileExists(FileList.FileName) then - { Load tag data } - if FileTag.ReadFromFile(FileList.FileName) then - if FileTag.Exists then - begin - { Fill captions } - TagExistsValue.Text := 'Yes'; - VersionValue.Text := FormatFloat('0,000', FileTag.Version); - SizeValue.Text := IntToStr(FileTag.Size) + ' bytes'; - TitleEdit.Text := FileTag.Title; - ArtistEdit.Text := FileTag.Artist; - AlbumEdit.Text := FileTag.Album; - if FileTag.Track > 0 then TrackEdit.Text := IntToStr(FileTag.Track); - YearEdit.Text := FileTag.Year; - GenreEdit.Text := FileTag.Genre; - CommentEdit.Text := FileTag.Comment; - CopyrightEdit.Text := FileTag.Copyright; - end - else - { Tag not found } - TagExistsValue.Text := 'No' - else - { Read error } - ShowMessage('Can not read tag from the file: ' + FileList.FileName) - else - { File does not exist } - ShowMessage('The file does not exist: ' + FileList.FileName); -end; - -procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); -begin - { Free memory } - FileTag.Free; -end; - -procedure TMainForm.SaveButtonClick(Sender: TObject); -var - Value, Code: Integer; -begin - { Prepare tag data } - FileTag.Title := TitleEdit.Text; - FileTag.Artist := ArtistEdit.Text; - FileTag.Album := AlbumEdit.Text; - Val(TrackEdit.Text, Value, Code); - if (Code = 0) and (Value > 0) then FileTag.Track := Value - else FileTag.Track := 0; - FileTag.Year := YearEdit.Text; - FileTag.Genre := GenreEdit.Text; - FileTag.Comment := CommentEdit.Text; - FileTag.Copyright := CopyrightEdit.Text; - { Save tag data } - if (not FileExists(FileList.FileName)) or - (not FileTag.SaveToFile(FileList.FileName)) then - ShowMessage('Can not save tag to the file: ' + FileList.FileName); - FileListChange(Self); -end; - -procedure TMainForm.RemoveButtonClick(Sender: TObject); -begin - { Delete tag data } - if (FileExists(FileList.FileName)) and - (FileTag.RemoveFromFile(FileList.FileName)) then ClearAll - else ShowMessage('Can not remove tag from the file: ' + FileList.FileName); -end; - -procedure TMainForm.CloseButtonClick(Sender: TObject); -begin - { Exit } - Close; -end; - -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.cfg b/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.cfg deleted file mode 100644 index dc18277..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.cfg +++ /dev/null @@ -1,35 +0,0 @@ --$A8 --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$YD --$Z1 --cg --AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; --H+ --W+ --M --$M16384,1048576 --K$00400000 --LE"c:\program files\borland\delphi6\Projects\Bpl" --LN"c:\program files\borland\delphi6\Projects\Bpl" diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.dof b/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.dof deleted file mode 100644 index 216ddb6..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.dof +++ /dev/null @@ -1,96 +0,0 @@ -[FileVersion] -Version=6.0 -[Compiler] -A=8 -B=0 -C=1 -D=1 -E=0 -F=0 -G=1 -H=1 -I=1 -J=0 -K=0 -L=1 -M=0 -N=1 -O=1 -P=1 -Q=0 -R=0 -S=0 -T=0 -U=0 -V=1 -W=0 -X=1 -Y=1 -Z=1 -ShowHints=1 -ShowWarnings=1 -UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; -[Linker] -MapFile=0 -OutputObjs=0 -ConsoleApp=1 -DebugInfo=0 -RemoteSymbols=0 -MinStackSize=16384 -MaxStackSize=1048576 -ImageBase=4194304 -ExeDescription= -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages=vcl;rtl;dbrtl;adortl;vcldb;vclx;bdertl;vcldbx;ibxpress;dsnap;cds;bdecds;qrpt;teeui;teedb;tee;dss;teeqr;visualclx;visualdbclx;dsnapcrba;dsnapcon;VclSmp;vclshlctrls;vclie;xmlrtl;inet;inetdbbde;inetdbxpress;inetdb;nmfast;webdsnap;websnap;dbexpress;dbxcds;indy;dclOffice2k -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams= -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang= -RootDir= -[Version Info] -IncludeVerInfo=0 -AutoIncBuild=0 -MajorVer=1 -MinorVer=0 -Release=0 -Build=0 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1031 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=1.0.0.0 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=1.0.0.0 -Comments= -[HistoryLists\hlUnitAliases] -Count=1 -Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; -[HistoryLists\hlUnitOutputDirectory] -Count=1 -Item0=DCU -[HistoryLists\hlOutputDirectorry] -Count=1 -Item0=Data diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.dpr b/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.dpr deleted file mode 100644 index 78f2042..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Test; - -uses - Forms, - Main in 'Main.pas' {MainForm}, - APEtag in 'APEtag.pas'; - -{$R *.res} - -begin - Application.Initialize; - Application.Title := 'APEtag Test'; - Application.CreateForm(TMainForm, MainForm); - Application.Run; -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.res b/MAC_SDK/3rd Party/TMonkey (Delphi)/APEtag/Test.res deleted file mode 100644 index 1ce496d085d8fc299deb9603aafc38a537e67933..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3780 zcmZQzU|>*SU|{(FAA&)AWSqeYlV@i5|DO>oB_P1g0%kBUFlaC^FbF`+U}WHc2t$-1 z*l>OW149D?14Batgkop_F&PdVIKXh=&H;uGrRQ{_lc>MQZ$oZecFya3MhAscM;0qpx-2W;Jt^Yk3 z=KjxN*!q70!`c5^@C6UUw*M*&hyHsooco`{aO?jBhG+k`;0qpx|Nm7O{{Q!2`2RnL z;s5^$4F5suaR(2>|7|J^{||XE{6Ck&@c-5XhX2pD;0qpx|G6p*|64s6{?E-}_`h`m z!~e5e@T49FhW{!m4F5em82;zvF#Mk|f#Lraka`h@SOz(U8U_u9*$hSuyBKU3ZZfzr zd|(J=_^*=7@ZY1A;eXCthW`_`GW_3imcfoeiy@Z5o}q>zgkd&ACc`d3T+V-nTNC~>Jlpc0L4?7ML5?AoL4%=&!H8itgAKzj1~-PA4517k7;;tq zGqigAXPBGwpJD5S{|slh{AXZeV`C5!5@L{-muJw?(P6N(v}AB~b!7+&3Sx+lk7vlq z$ziCds9 z|5y>qe+f2<;j!XN#k+U!B9tpCD!#t^8gBe!Ma7rjUVnq}Up{`R`10E~82_cJs_IL{ zmvHwzR(+-lHeVH@0VI#iXL$Meu__2aq`^*j3<6*lgn0S#CDd*I`xzMivokRKV`gCZ z!_2_&gPDQh0|>J-Fnr*L;0OE+3=?&;H~Z{FZi z`0VLZMMXu$m+!DEc=-$@3sUe5n}U~M&0r;Ou~_j8rW>RJ(*PvhAR90&c(w_o4~C&7 zFeARGr$fu{ed;+vNsVHkdk<~}aPXK!F~Ao>}q|K7b+e2Fao z6y5rlid;zYXu25~UcOX(3YLHQOzGLPr>KTAFfhD)2Dbn0+h_Og-Ft>+I7I&C8^yOz zpFVwd?-{z~Ao-^t_q}}i?c2*|-@c*gfA{j;)3=IGpDI54_U+rZr~kj9h0QZ1ZY6Nw zK;*xn%D?1NQ&Usp0x5Xz=z6qjxW28L(vpP{A7|6p*S{{R05`~UwL z)PUum|Bk3=H=F7#QmRKVbg<{|Ed3|3CQu|NmqEUx|T%!2r}Y{LjbW%izf1 u$>7J}$>7Z3&)^636axcty9U%~VPX&v0MQ%_px!7WgMtEt2Wk_6T0#H`L}pt6 diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/ID3v1.pas b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/ID3v1.pas deleted file mode 100644 index 197a62c..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/ID3v1.pas +++ /dev/null @@ -1,475 +0,0 @@ -{ *************************************************************************** } -{ } -{ Audio Tools Library (Freeware) } -{ Class TID3v1 - for manipulating with ID3v1 tags } -{ } -{ Copyright (c) 2001,2002 by Jurgen Faul } -{ E-mail: jfaul@gmx.de } -{ http://jfaul.de/atl } -{ } -{ Version 1.0 (25 July 2001) } -{ - Reading & writing support for ID3v1.x tags } -{ - Tag info: title, artist, album, track, year, genre, comment } -{ } -{ *************************************************************************** } - -unit ID3v1; - -interface - -uses - Classes, SysUtils; - -const - MAX_MUSIC_GENRES = 148; { Max. number of music genres } - DEFAULT_GENRE = 255; { Index for default genre } - - { Used with VersionID property } - TAG_VERSION_1_0 = 1; { Index for ID3v1.0 tag } - TAG_VERSION_1_1 = 2; { Index for ID3v1.1 tag } - -var - MusicGenre: array [0..MAX_MUSIC_GENRES - 1] of string; { Genre names } - -type - { Used in TID3v1 class } - String04 = string[4]; { String with max. 4 symbols } - String30 = string[30]; { String with max. 30 symbols } - - { Class TID3v1 } - TID3v1 = class(TObject) - private - { Private declarations } - FExists: Boolean; - FVersionID: Byte; - FTitle: String30; - FArtist: String30; - FAlbum: String30; - FYear: String04; - FComment: String30; - FTrack: Byte; - FGenreID: Byte; - procedure FSetTitle(const NewTitle: String30); - procedure FSetArtist(const NewArtist: String30); - procedure FSetAlbum(const NewAlbum: String30); - procedure FSetYear(const NewYear: String04); - procedure FSetComment(const NewComment: String30); - procedure FSetTrack(const NewTrack: Byte); - procedure FSetGenreID(const NewGenreID: Byte); - function FGetGenre: string; - public - { Public declarations } - constructor Create; { Create object } - procedure ResetData; { Reset all data } - function ReadFromFile(const FileName: string): Boolean; { Load tag } - function RemoveFromFile(const FileName: string): Boolean; { Delete tag } - function SaveToFile(const FileName: string): Boolean; { Save tag } - property Exists: Boolean read FExists; { True if tag found } - property VersionID: Byte read FVersionID; { Version code } - property Title: String30 read FTitle write FSetTitle; { Song title } - property Artist: String30 read FArtist write FSetArtist; { Artist name } - property Album: String30 read FAlbum write FSetAlbum; { Album name } - property Year: String04 read FYear write FSetYear; { Year } - property Comment: String30 read FComment write FSetComment; { Comment } - property Track: Byte read FTrack write FSetTrack; { Track number } - property GenreID: Byte read FGenreID write FSetGenreID; { Genre code } - property Genre: string read FGetGenre; { Genre name } - end; - -implementation - -type - { Real structure of ID3v1 tag } - TagRecord = record - Header: array [1..3] of Char; { Tag header - must be "TAG" } - Title: array [1..30] of Char; { Title data } - Artist: array [1..30] of Char; { Artist data } - Album: array [1..30] of Char; { Album data } - Year: array [1..4] of Char; { Year data } - Comment: array [1..30] of Char; { Comment data } - Genre: Byte; { Genre data } - end; - -{ ********************* Auxiliary functions & procedures ******************** } - -function ReadTag(const FileName: string; var TagData: TagRecord): Boolean; -var - SourceFile: file; -begin - try - Result := true; - { Set read-access and open file } - AssignFile(SourceFile, FileName); - FileMode := 0; - Reset(SourceFile, 1); - { Read tag } - Seek(SourceFile, FileSize(SourceFile) - 128); - BlockRead(SourceFile, TagData, 128); - CloseFile(SourceFile); - except - { Error } - Result := false; - end; -end; - -{ --------------------------------------------------------------------------- } - -function RemoveTag(const FileName: string): Boolean; -var - SourceFile: file; -begin - try - Result := true; - { Allow write-access and open file } - FileSetAttr(FileName, 0); - AssignFile(SourceFile, FileName); - FileMode := 2; - Reset(SourceFile, 1); - { Delete tag } - Seek(SourceFile, FileSize(SourceFile) - 128); - Truncate(SourceFile); - CloseFile(SourceFile); - except - { Error } - Result := false; - end; -end; - -{ --------------------------------------------------------------------------- } - -function SaveTag(const FileName: string; TagData: TagRecord): Boolean; -var - SourceFile: file; -begin - try - Result := true; - { Allow write-access and open file } - FileSetAttr(FileName, 0); - AssignFile(SourceFile, FileName); - FileMode := 2; - Reset(SourceFile, 1); - { Write tag } - Seek(SourceFile, FileSize(SourceFile)); - BlockWrite(SourceFile, TagData, SizeOf(TagData)); - CloseFile(SourceFile); - except - { Error } - Result := false; - end; -end; - -{ --------------------------------------------------------------------------- } - -function GetTagVersion(const TagData: TagRecord): Byte; -begin - Result := TAG_VERSION_1_0; - { Terms for ID3v1.1 } - if ((TagData.Comment[29] = #0) and (TagData.Comment[30] <> #0)) or - ((TagData.Comment[29] = #32) and (TagData.Comment[30] <> #32)) then - Result := TAG_VERSION_1_1; -end; - -{ ********************** Private functions & procedures ********************* } - -procedure TID3v1.FSetTitle(const NewTitle: String30); -begin - FTitle := TrimRight(NewTitle); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v1.FSetArtist(const NewArtist: String30); -begin - FArtist := TrimRight(NewArtist); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v1.FSetAlbum(const NewAlbum: String30); -begin - FAlbum := TrimRight(NewAlbum); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v1.FSetYear(const NewYear: String04); -begin - FYear := TrimRight(NewYear); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v1.FSetComment(const NewComment: String30); -begin - FComment := TrimRight(NewComment); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v1.FSetTrack(const NewTrack: Byte); -begin - FTrack := NewTrack; -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v1.FSetGenreID(const NewGenreID: Byte); -begin - FGenreID := NewGenreID; -end; - -{ --------------------------------------------------------------------------- } - -function TID3v1.FGetGenre: string; -begin - Result := ''; - { Return an empty string if the current GenreID is not valid } - if FGenreID in [0..MAX_MUSIC_GENRES - 1] then Result := MusicGenre[FGenreID]; -end; - -{ ********************** Public functions & procedures ********************** } - -constructor TID3v1.Create; -begin - inherited; - ResetData; -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v1.ResetData; -begin - FExists := false; - FVersionID := TAG_VERSION_1_0; - FTitle := ''; - FArtist := ''; - FAlbum := ''; - FYear := ''; - FComment := ''; - FTrack := 0; - FGenreID := DEFAULT_GENRE; -end; - -{ --------------------------------------------------------------------------- } - -function TID3v1.ReadFromFile(const FileName: string): Boolean; -var - TagData: TagRecord; -begin - { Reset and load tag data from file to variable } - ResetData; - Result := ReadTag(FileName, TagData); - { Process data if loaded and tag header OK } - if (Result) and (TagData.Header = 'TAG') then - begin - FExists := true; - FVersionID := GetTagVersion(TagData); - { Fill properties with tag data } - FTitle := TrimRight(TagData.Title); - FArtist := TrimRight(TagData.Artist); - FAlbum := TrimRight(TagData.Album); - FYear := TrimRight(TagData.Year); - if FVersionID = TAG_VERSION_1_0 then - FComment := TrimRight(TagData.Comment) - else - begin - FComment := TrimRight(Copy(TagData.Comment, 1, 28)); - FTrack := Ord(TagData.Comment[30]); - end; - FGenreID := TagData.Genre; - end; -end; - -{ --------------------------------------------------------------------------- } - -function TID3v1.RemoveFromFile(const FileName: string): Boolean; -var - TagData: TagRecord; -begin - { Find tag } - Result := ReadTag(FileName, TagData); - { Delete tag if loaded and tag header OK } - if (Result) and (TagData.Header = 'TAG') then Result := RemoveTag(FileName); -end; - -{ --------------------------------------------------------------------------- } - -function TID3v1.SaveToFile(const FileName: string): Boolean; -var - TagData: TagRecord; -begin - { Prepare tag record } - FillChar(TagData, SizeOf(TagData), 0); - TagData.Header := 'TAG'; - Move(FTitle[1], TagData.Title, Length(FTitle)); - Move(FArtist[1], TagData.Artist, Length(FArtist)); - Move(FAlbum[1], TagData.Album, Length(FAlbum)); - Move(FYear[1], TagData.Year, Length(FYear)); - Move(FComment[1], TagData.Comment, Length(FComment)); - if FTrack > 0 then - begin - TagData.Comment[29] := #0; - TagData.Comment[30] := Chr(FTrack); - end; - TagData.Genre := FGenreID; - { Delete old tag and write new tag } - Result := (RemoveFromFile(FileName)) and (SaveTag(FileName, TagData)); -end; - -{ ************************** Initialize music genres ************************ } - -initialization -begin - { Standard genres } - MusicGenre[0] := 'Blues'; - MusicGenre[1] := 'Classic Rock'; - MusicGenre[2] := 'Country'; - MusicGenre[3] := 'Dance'; - MusicGenre[4] := 'Disco'; - MusicGenre[5] := 'Funk'; - MusicGenre[6] := 'Grunge'; - MusicGenre[7] := 'Hip-Hop'; - MusicGenre[8] := 'Jazz'; - MusicGenre[9] := 'Metal'; - MusicGenre[10] := 'New Age'; - MusicGenre[11] := 'Oldies'; - MusicGenre[12] := 'Other'; - MusicGenre[13] := 'Pop'; - MusicGenre[14] := 'R&B'; - MusicGenre[15] := 'Rap'; - MusicGenre[16] := 'Reggae'; - MusicGenre[17] := 'Rock'; - MusicGenre[18] := 'Techno'; - MusicGenre[19] := 'Industrial'; - MusicGenre[20] := 'Alternative'; - MusicGenre[21] := 'Ska'; - MusicGenre[22] := 'Death Metal'; - MusicGenre[23] := 'Pranks'; - MusicGenre[24] := 'Soundtrack'; - MusicGenre[25] := 'Euro-Techno'; - MusicGenre[26] := 'Ambient'; - MusicGenre[27] := 'Trip-Hop'; - MusicGenre[28] := 'Vocal'; - MusicGenre[29] := 'Jazz+Funk'; - MusicGenre[30] := 'Fusion'; - MusicGenre[31] := 'Trance'; - MusicGenre[32] := 'Classical'; - MusicGenre[33] := 'Instrumental'; - MusicGenre[34] := 'Acid'; - MusicGenre[35] := 'House'; - MusicGenre[36] := 'Game'; - MusicGenre[37] := 'Sound Clip'; - MusicGenre[38] := 'Gospel'; - MusicGenre[39] := 'Noise'; - MusicGenre[40] := 'AlternRock'; - MusicGenre[41] := 'Bass'; - MusicGenre[42] := 'Soul'; - MusicGenre[43] := 'Punk'; - MusicGenre[44] := 'Space'; - MusicGenre[45] := 'Meditative'; - MusicGenre[46] := 'Instrumental Pop'; - MusicGenre[47] := 'Instrumental Rock'; - MusicGenre[48] := 'Ethnic'; - MusicGenre[49] := 'Gothic'; - MusicGenre[50] := 'Darkwave'; - MusicGenre[51] := 'Techno-Industrial'; - MusicGenre[52] := 'Electronic'; - MusicGenre[53] := 'Pop-Folk'; - MusicGenre[54] := 'Eurodance'; - MusicGenre[55] := 'Dream'; - MusicGenre[56] := 'Southern Rock'; - MusicGenre[57] := 'Comedy'; - MusicGenre[58] := 'Cult'; - MusicGenre[59] := 'Gangsta'; - MusicGenre[60] := 'Top 40'; - MusicGenre[61] := 'Christian Rap'; - MusicGenre[62] := 'Pop/Funk'; - MusicGenre[63] := 'Jungle'; - MusicGenre[64] := 'Native American'; - MusicGenre[65] := 'Cabaret'; - MusicGenre[66] := 'New Wave'; - MusicGenre[67] := 'Psychadelic'; - MusicGenre[68] := 'Rave'; - MusicGenre[69] := 'Showtunes'; - MusicGenre[70] := 'Trailer'; - MusicGenre[71] := 'Lo-Fi'; - MusicGenre[72] := 'Tribal'; - MusicGenre[73] := 'Acid Punk'; - MusicGenre[74] := 'Acid Jazz'; - MusicGenre[75] := 'Polka'; - MusicGenre[76] := 'Retro'; - MusicGenre[77] := 'Musical'; - MusicGenre[78] := 'Rock & Roll'; - MusicGenre[79] := 'Hard Rock'; - { Extended genres } - MusicGenre[80] := 'Folk'; - MusicGenre[81] := 'Folk-Rock'; - MusicGenre[82] := 'National Folk'; - MusicGenre[83] := 'Swing'; - MusicGenre[84] := 'Fast Fusion'; - MusicGenre[85] := 'Bebob'; - MusicGenre[86] := 'Latin'; - MusicGenre[87] := 'Revival'; - MusicGenre[88] := 'Celtic'; - MusicGenre[89] := 'Bluegrass'; - MusicGenre[90] := 'Avantgarde'; - MusicGenre[91] := 'Gothic Rock'; - MusicGenre[92] := 'Progessive Rock'; - MusicGenre[93] := 'Psychedelic Rock'; - MusicGenre[94] := 'Symphonic Rock'; - MusicGenre[95] := 'Slow Rock'; - MusicGenre[96] := 'Big Band'; - MusicGenre[97] := 'Chorus'; - MusicGenre[98] := 'Easy Listening'; - MusicGenre[99] := 'Acoustic'; - MusicGenre[100]:= 'Humour'; - MusicGenre[101]:= 'Speech'; - MusicGenre[102]:= 'Chanson'; - MusicGenre[103]:= 'Opera'; - MusicGenre[104]:= 'Chamber Music'; - MusicGenre[105]:= 'Sonata'; - MusicGenre[106]:= 'Symphony'; - MusicGenre[107]:= 'Booty Bass'; - MusicGenre[108]:= 'Primus'; - MusicGenre[109]:= 'Porn Groove'; - MusicGenre[110]:= 'Satire'; - MusicGenre[111]:= 'Slow Jam'; - MusicGenre[112]:= 'Club'; - MusicGenre[113]:= 'Tango'; - MusicGenre[114]:= 'Samba'; - MusicGenre[115]:= 'Folklore'; - MusicGenre[116]:= 'Ballad'; - MusicGenre[117]:= 'Power Ballad'; - MusicGenre[118]:= 'Rhythmic Soul'; - MusicGenre[119]:= 'Freestyle'; - MusicGenre[120]:= 'Duet'; - MusicGenre[121]:= 'Punk Rock'; - MusicGenre[122]:= 'Drum Solo'; - MusicGenre[123]:= 'A capella'; - MusicGenre[124]:= 'Euro-House'; - MusicGenre[125]:= 'Dance Hall'; - MusicGenre[126]:= 'Goa'; - MusicGenre[127]:= 'Drum & Bass'; - MusicGenre[128]:= 'Club-House'; - MusicGenre[129]:= 'Hardcore'; - MusicGenre[130]:= 'Terror'; - MusicGenre[131]:= 'Indie'; - MusicGenre[132]:= 'BritPop'; - MusicGenre[133]:= 'Negerpunk'; - MusicGenre[134]:= 'Polsk Punk'; - MusicGenre[135]:= 'Beat'; - MusicGenre[136]:= 'Christian Gangsta Rap'; - MusicGenre[137]:= 'Heavy Metal'; - MusicGenre[138]:= 'Black Metal'; - MusicGenre[139]:= 'Crossover'; - MusicGenre[140]:= 'Contemporary Christian'; - MusicGenre[141]:= 'Christian Rock'; - MusicGenre[142]:= 'Merengue'; - MusicGenre[143]:= 'Salsa'; - MusicGenre[144]:= 'Trash Metal'; - MusicGenre[145]:= 'Anime'; - MusicGenre[146]:= 'JPop'; - MusicGenre[147]:= 'Synthpop'; -end; - -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Info.txt b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Info.txt deleted file mode 100644 index 3e8f48a..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Info.txt +++ /dev/null @@ -1,17 +0,0 @@ -ID3v1.pas -Tested with Borland Delphi 3,4,5,6 - -{ *************************************************************************** } -{ } -{ Audio Tools Library (Freeware) } -{ Class TID3v1 - for manipulating with ID3v1 tags } -{ } -{ Copyright (c) 2001,2002 by Jurgen Faul } -{ E-mail: jfaul@gmx.de } -{ http://jfaul.de/atl } -{ } -{ Version 1.0 (25 July 2001) } -{ - Reading & writing support for ID3v1.x tags } -{ - Tag info: title, artist, album, track, year, genre, comment } -{ } -{ *************************************************************************** } \ No newline at end of file diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Main.dfm b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Main.dfm deleted file mode 100644 index 4a0acfae3fd04c75e1cb411cd0be89ce158b7029..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7324 zcmey*#Sr4_=;`O?ALPqmAkZnpzz`DPX22QZo0ysBmS2?10b{WEq^6ZHw=pt@#<-JLlvVr#h9El;r1eJLMOpq!xK5=jRo3^CV>kR~DC~=K7}Q zm2xFz`ex>3=4MuOTVm2v54hz)-c5fgx!c z1A|vF1A|cj!-*1;o&BG|!{a}Ls_K6R28MqO3=DS|7#MakFfdGGU|=X_ zU|!{a~0D%JlCs~G+>Ok%jhP{pv5A&FrcgBL?FgAqdj z!~ZM)8UAnl&+xzRKg0j*{|x^<{xken{m<}^;UB{thC2*98Fn&EW0=NJ%uvh_09OBj z;s3@*4FCJCF#OLx#_-=`2g83=km;)!?l4SZ*vU}EFpVLJp_svoA%MY%;s2G#4F5MC zXZYW@n&E$TKf`~IVut^!;S3-j++px!*vVkaFpa^Gp_oCHA%H=W;s2E@4F5N7Wcc6L z$M8Qpo8iBQ2g83=RUDzi!0`X^6^8%EH!}QR-N*31Kbzryu?NHda8-u?p$rUnJQ)~v z+A=UqGh|>WR%KuakYr%^|KSS5|3@1c{$J^1_!f^cmMuye@ z`xyHFXEPN4_h1PBuZk=AFkJb6g<<3WjSPMN`xvtSXES*G_h3-{uZk=AFkJcnm|^4p z;|zWOS2JY)?`QD%U(BHTKb!$q0A2b2fnnqSM+|-cuP|i)KgQtke+PpqC~!a+O8{N@ z|DR#w|Njhq|Nk>&|Nqb6@&7-ADyUq+5kQ|lePVd_>>0zYTeld_ojb>H=+GgCZQHgn ztXj2-VcxuX43j2JVrXk?W2maCV#v$OV@OI$Vh9ThWAO6wVz9HbV=yu@Vo+04V~~=P zV&LQBWBBm-R{2fq~)mQv`Sq;(z=0?J)#Ah4G)D z@ZW#{NCYnb?a|{$j~_pV@=bwF2id$U|?W)Kn@0#%}C`es4j9qs*f0$ zz=bLn0(&_NiX%{23$BcC#}lYNf?<%^6&-NU4&v8?Dk=yjjt{B;k=6J2_k-%H|Ns9( z^fNFp{6Lq7D1gZS`0)cp9^?pqum*@cm{*##PDfPfJ*>Mh&M>> z5o9LJOymX%qNxIIYk-x2S{k6%2r5RB{|{<>fZ8X>Dv;$tEr>_o9)X%5;C2j19jg4! zojbpMd;0w4>$i^|Lr7Hl?ca8O`}P>5;1QUFwrwEp`~U6R*6lk%=7SnmP=}!E2e|;G z;PGQfOA1{-SRT}j`UYx8VY;uXstW49Z(#R5fwaZo_E&zZg1Hau4RrIfE2}_OfC2$z zIIQgk*AJ2eV@M!9LDvtK`}PP-L41JfKOY|-nEM`K3qQ|qK6u^d?&$+I8`O>j2fD)GxRad;DBmE7{e7(l$e~2a0xU_;SQ0+SH0tovV85np%V5*(+ zE8yzERxrN+$2QzsjPN1kl?=!R^0N3Q7H6|@Yw6_{*jsDqB^IP2tY89-XlEqmrKhs< z!EAB{^BEY}L!i?F;Gu5_8)EYhNYpgI(nv5YKqc9n6Z4W&b2#BSniZ@WVIdEAR6R2} zn_U1b12NV)Co?%4VIxmaYHofRbXEezN_c8OSP8d^4WbKS7dPB4L5LJq%eaCQv07z- z={vYpEFe7yi@4wx@q;8#tYHmtP01|b1eYKn7T7yX8Q{X}3$)B(E`-G$lPITeVuep? zUV2FelN`bZX3#i3NIMs#7y&VnO%j1Rmas`IFq1gJg$cSrCPW*=3O5LxlhF+dff~f5 z2umEuUSmRdjSXfF2dHR*8^e46oV=Og=2&7ghXr8{JIowzXz>I$3L4raP!|ynBTfbe z&JgE(NMXVYE@WUlaG*0=Kr#T#ZOjYdMT#gZc!r6cFS*#ID8IlZzdR3=*HJPg!p$5o zHzVrHu*96wRIn{jXJ3UT5~fO600^^(Bqjxywj;$vW7005UiG`0W$ diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Main.pas b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Main.pas deleted file mode 100644 index aca653e..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Main.pas +++ /dev/null @@ -1,162 +0,0 @@ -unit Main; - -interface - -uses - Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - StdCtrls, FileCtrl, ExtCtrls, ID3v1; - -type - TMainForm = class(TForm) - DriveList: TDriveComboBox; - FolderList: TDirectoryListBox; - FileList: TFileListBox; - CloseButton: TButton; - RemoveButton: TButton; - SaveButton: TButton; - InfoBevel: TBevel; - IconImage: TImage; - TagExistsLabel: TLabel; - TagVersionLabel: TLabel; - TitleLabel: TLabel; - ArtistLabel: TLabel; - AlbumLabel: TLabel; - YearLabel: TLabel; - CommentLabel: TLabel; - TrackLabel: TLabel; - GenreLabel: TLabel; - TitleEdit: TEdit; - ArtistEdit: TEdit; - AlbumEdit: TEdit; - TrackEdit: TEdit; - YearEdit: TEdit; - CommentEdit: TEdit; - GenreComboBox: TComboBox; - TagExistsValue: TEdit; - TagVersionValue: TEdit; - procedure CloseButtonClick(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure FileListChange(Sender: TObject); - procedure FormClose(Sender: TObject; var Action: TCloseAction); - procedure SaveButtonClick(Sender: TObject); - procedure RemoveButtonClick(Sender: TObject); - private - { Private declarations } - FileTag: TID3v1; - procedure ClearAll; - end; - -var - MainForm: TMainForm; - -implementation - -{$R *.dfm} - -procedure TMainForm.ClearAll; -begin - { Clear all captions } - TagExistsValue.Text := ''; - TagVersionValue.Text := ''; - TitleEdit.Text := ''; - ArtistEdit.Text := ''; - AlbumEdit.Text := ''; - TrackEdit.Text := ''; - YearEdit.Text := ''; - GenreComboBox.ItemIndex := 0; - CommentEdit.Text := ''; -end; - -procedure TMainForm.CloseButtonClick(Sender: TObject); -begin - { Exit } - Close; -end; - -procedure TMainForm.FormCreate(Sender: TObject); -var - Iterator: Integer; -begin - { Create object } - FileTag := TID3v1.Create; - { Fill and initialize genres } - GenreComboBox.Items.Add(''); - for Iterator := 0 to MAX_MUSIC_GENRES - 1 do - GenreComboBox.Items.Add(MusicGenre[Iterator]); - { Reset } - ClearAll; -end; - -procedure TMainForm.FileListChange(Sender: TObject); -begin - { Clear captions } - ClearAll; - if FileList.FileName = '' then exit; - if FileExists(FileList.FileName) then - { Load tag data } - if FileTag.ReadFromFile(FileList.FileName) then - if FileTag.Exists then - begin - { Fill captions } - TagExistsValue.Text := 'Yes'; - if FileTag.VersionID = TAG_VERSION_1_0 then - TagVersionValue.Text := '1.0' - else - TagVersionValue.Text := '1.1'; - TitleEdit.Text := FileTag.Title; - ArtistEdit.Text := FileTag.Artist; - AlbumEdit.Text := FileTag.Album; - TrackEdit.Text := IntToStr(FileTag.Track); - YearEdit.Text := FileTag.Year; - if FileTag.GenreID < MAX_MUSIC_GENRES then - GenreComboBox.ItemIndex := FileTag.GenreID + 1; - CommentEdit.Text := FileTag.Comment; - end - else - { Tag not found } - TagExistsValue.Text := 'No' - else - { Read error } - ShowMessage('Can not read tag from the file: ' + FileList.FileName) - else - { File does not exist } - ShowMessage('The file does not exist: ' + FileList.FileName); -end; - -procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); -begin - { Free memory } - FileTag.Free; -end; - -procedure TMainForm.SaveButtonClick(Sender: TObject); -var - Value, Code: Integer; -begin - { Prepare tag data } - FileTag.Title := TitleEdit.Text; - FileTag.Artist := ArtistEdit.Text; - FileTag.Album := AlbumEdit.Text; - FileTag.Year := YearEdit.Text; - Val(TrackEdit.Text, Value, Code); - if (Code = 0) and (Value > 0) then FileTag.Track := Value - else FileTag.Track := 0; - if GenreComboBox.ItemIndex = 0 then FileTag.GenreID := DEFAULT_GENRE - else FileTag.GenreID := GenreComboBox.ItemIndex - 1; - FileTag.Comment := CommentEdit.Text; - { Save tag data } - if (not FileExists(FileList.FileName)) or - (not FileTag.SaveToFile(FileList.FileName)) then - ShowMessage('Can not save tag to the file: ' + FileList.FileName); - FileListChange(Self); -end; - -procedure TMainForm.RemoveButtonClick(Sender: TObject); -begin - { Delete tag data } - if (FileExists(FileList.FileName)) and - (FileTag.RemoveFromFile(FileList.FileName)) then ClearAll - else ShowMessage('Can not remove tag from the file: ' + FileList.FileName); -end; - -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.cfg b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.cfg deleted file mode 100644 index dc18277..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.cfg +++ /dev/null @@ -1,35 +0,0 @@ --$A8 --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$YD --$Z1 --cg --AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; --H+ --W+ --M --$M16384,1048576 --K$00400000 --LE"c:\program files\borland\delphi6\Projects\Bpl" --LN"c:\program files\borland\delphi6\Projects\Bpl" diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.dof b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.dof deleted file mode 100644 index 216ddb6..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.dof +++ /dev/null @@ -1,96 +0,0 @@ -[FileVersion] -Version=6.0 -[Compiler] -A=8 -B=0 -C=1 -D=1 -E=0 -F=0 -G=1 -H=1 -I=1 -J=0 -K=0 -L=1 -M=0 -N=1 -O=1 -P=1 -Q=0 -R=0 -S=0 -T=0 -U=0 -V=1 -W=0 -X=1 -Y=1 -Z=1 -ShowHints=1 -ShowWarnings=1 -UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; -[Linker] -MapFile=0 -OutputObjs=0 -ConsoleApp=1 -DebugInfo=0 -RemoteSymbols=0 -MinStackSize=16384 -MaxStackSize=1048576 -ImageBase=4194304 -ExeDescription= -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages=vcl;rtl;dbrtl;adortl;vcldb;vclx;bdertl;vcldbx;ibxpress;dsnap;cds;bdecds;qrpt;teeui;teedb;tee;dss;teeqr;visualclx;visualdbclx;dsnapcrba;dsnapcon;VclSmp;vclshlctrls;vclie;xmlrtl;inet;inetdbbde;inetdbxpress;inetdb;nmfast;webdsnap;websnap;dbexpress;dbxcds;indy;dclOffice2k -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams= -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang= -RootDir= -[Version Info] -IncludeVerInfo=0 -AutoIncBuild=0 -MajorVer=1 -MinorVer=0 -Release=0 -Build=0 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1031 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=1.0.0.0 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=1.0.0.0 -Comments= -[HistoryLists\hlUnitAliases] -Count=1 -Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; -[HistoryLists\hlUnitOutputDirectory] -Count=1 -Item0=DCU -[HistoryLists\hlOutputDirectorry] -Count=1 -Item0=Data diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.dpr b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.dpr deleted file mode 100644 index 8c4aa94..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Test; - -uses - Forms, - Main in 'Main.pas' {MainForm}, - ID3v1 in 'ID3v1.pas'; - -{$R *.res} - -begin - Application.Initialize; - Application.Title := 'ID3v1 Test'; - Application.CreateForm(TMainForm, MainForm); - Application.Run; -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.res b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v1/Test.res deleted file mode 100644 index 3c80f0b2ca5ade8edf7f37ea8d8112a1431f3c53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3780 zcmZQzU|>*SU|{(FAA&)AWSqeYlV@i5|DO>oB_P1g0%kBUFlaC^FbF`+U}WHc2t$-1 z*l>OW149D?14Batgkop_F&PdVIKXh=&H;uGrRQ{_lc>MQZ$oZecFya3MhAscM;0qpx-2W;Jt^Yk3 z=KjxN*!q70!`c5^@C6UUw*M*&hyHsooco`{aO?jBhG+k`;0qpx|Nm7O{{Q!2`2RnL z;s5^$4F5suaR(2>|7|J^{||XE{6Ck&@c-5XhX2pD;0qpx|G6p*|64s6{?E-}_`h`m z!~e5e@T49FhW{!m4F5em82;zvF#Mk|f#Lraka`h@SOz(U8U_u9*$hSuyBKU3ZZfzr zd|(J=_^*=7@ZY1A;eXCthW`_`GW_3imcfoeiy@Z5o}q>zgkd&ACc`d3T+V-nTNC~>Jlpc0L4?7ML5?AoL4%=&!H8itgAKzj1~-PA4517k7;;tq zGqigAXPBGwpJD5S{|slh{AXZeV`C5!5@L{-muJw?(P6N(v}AB~b!7+&3Sx+lk7vlq z$ziCds9C?wgA0dLDZEZilfBW|J z>rW8=7Z4vL0G0ppy);7AXJd(f=Un*HHOyM~|Ya z|MvesL<>ayH$lPw@8ACa@`)YJ|Mvd<7YK)ef#KV?Z~wpj|HSYOD)J31096bXgHs2X z85l^$>vSmeKb11W(>qnST#+BB&9zJcBM8BKorw`nl0dk>VF31tUSR{psU7T=Gz9RCysGA(;EVef{$3ad|AB$w{|5%f{~s8bVb=avVqjn}0JRPO^D+1`I5K!L r_%V1gI5YS&_`yAg+^zvNT9_CF1VA(g1E@F3$e^GA;epyjpq3B-GF$kj diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/ID3v2.pas b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/ID3v2.pas deleted file mode 100644 index 1c19978..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/ID3v2.pas +++ /dev/null @@ -1,631 +0,0 @@ -{ *************************************************************************** } -{ } -{ Audio Tools Library (Freeware) } -{ Class TID3v2 - for manipulating with ID3v2 tags } -{ } -{ Copyright (c) 2001,2002 by Jurgen Faul } -{ E-mail: jfaul@gmx.de } -{ http://jfaul.de/atl } -{ } -{ Version 1.4 (24 March 2002) } -{ - Reading support for ID3v2.2.x & ID3v2.4.x tags } -{ } -{ Version 1.3 (16 February 2002) } -{ - Fixed bug with property Comment } -{ - Added info: composer, encoder, copyright, language, link } -{ } -{ Version 1.2 (17 October 2001) } -{ - Writing support for ID3v2.3.x tags } -{ - Fixed bug with track number detection } -{ - Fixed bug with tag reading } -{ } -{ Version 1.1 (31 August 2001) } -{ - Added public procedure ResetData } -{ } -{ Version 1.0 (14 August 2001) } -{ - Reading support for ID3v2.3.x tags } -{ - Tag info: title, artist, album, track, year, genre, comment } -{ } -{ *************************************************************************** } - -unit ID3v2; - -interface - -uses - Classes, SysUtils; - -const - TAG_VERSION_2_2 = 2; { Code for ID3v2.2.x tag } - TAG_VERSION_2_3 = 3; { Code for ID3v2.3.x tag } - TAG_VERSION_2_4 = 4; { Code for ID3v2.4.x tag } - -type - { Class TID3v2 } - TID3v2 = class(TObject) - private - { Private declarations } - FExists: Boolean; - FVersionID: Byte; - FSize: Integer; - FTitle: string; - FArtist: string; - FAlbum: string; - FTrack: Byte; - FYear: string; - FGenre: string; - FComment: string; - FComposer: string; - FEncoder: string; - FCopyright: string; - FLanguage: string; - FLink: string; - procedure FSetTitle(const NewTitle: string); - procedure FSetArtist(const NewArtist: string); - procedure FSetAlbum(const NewAlbum: string); - procedure FSetTrack(const NewTrack: Byte); - procedure FSetYear(const NewYear: string); - procedure FSetGenre(const NewGenre: string); - procedure FSetComment(const NewComment: string); - procedure FSetComposer(const NewComposer: string); - procedure FSetEncoder(const NewEncoder: string); - procedure FSetCopyright(const NewCopyright: string); - procedure FSetLanguage(const NewLanguage: string); - procedure FSetLink(const NewLink: string); - public - { Public declarations } - constructor Create; { Create object } - procedure ResetData; { Reset all data } - function ReadFromFile(const FileName: string): Boolean; { Load tag } - function SaveToFile(const FileName: string): Boolean; { Save tag } - function RemoveFromFile(const FileName: string): Boolean; { Delete tag } - property Exists: Boolean read FExists; { True if tag found } - property VersionID: Byte read FVersionID; { Version code } - property Size: Integer read FSize; { Total tag size } - property Title: string read FTitle write FSetTitle; { Song title } - property Artist: string read FArtist write FSetArtist; { Artist name } - property Album: string read FAlbum write FSetAlbum; { Album title } - property Track: Byte read FTrack write FSetTrack; { Track number } - property Year: string read FYear write FSetYear; { Release year } - property Genre: string read FGenre write FSetGenre; { Genre name } - property Comment: string read FComment write FSetComment; { Comment } - property Composer: string read FComposer write FSetComposer; { Composer } - property Encoder: string read FEncoder write FSetEncoder; { Encoder } - property Copyright: string read FCopyright write FSetCopyright; { (c) } - property Language: string read FLanguage write FSetLanguage; { Language } - property Link: string read FLink write FSetLink; { URL link } - end; - -implementation - -const - { ID3v2 tag ID } - ID3V2_ID = 'ID3'; - - { Max. number of supported tag frames } - ID3V2_FRAME_COUNT = 16; - - { Names of supported tag frames (ID3v2.3.x & ID3v2.4.x) } - ID3V2_FRAME_NEW: array [1..ID3V2_FRAME_COUNT] of string = - ('TIT2', 'TPE1', 'TALB', 'TRCK', 'TYER', 'TCON', 'COMM', 'TCOM', 'TENC', - 'TCOP', 'TLAN', 'WXXX', 'TDRC', 'TOPE', 'TIT1', 'TOAL'); - - { Names of supported tag frames (ID3v2.2.x) } - ID3V2_FRAME_OLD: array [1..ID3V2_FRAME_COUNT] of string = - ('TT2', 'TP1', 'TAL', 'TRK', 'TYE', 'TCO', 'COM', 'TCM', 'TEN', - 'TCR', 'TLA', 'WXX', 'TOR', 'TOA', 'TT1', 'TOT'); - -type - { Frame header (ID3v2.3.x & ID3v2.4.x) } - FrameHeaderNew = record - ID: array [1..4] of Char; { Frame ID } - Size: Integer; { Size excluding header } - Flags: Word; { Flags } - end; - - { Frame header (ID3v2.2.x) } - FrameHeaderOld = record - ID: array [1..3] of Char; { Frame ID } - Size: array [1..3] of Byte; { Size excluding header } - end; - - { ID3v2 header data - for internal use } - TagInfo = record - { Real structure of ID3v2 header } - ID: array [1..3] of Char; { Always "ID3" } - Version: Byte; { Version number } - Revision: Byte; { Revision number } - Flags: Byte; { Flags of tag } - Size: array [1..4] of Byte; { Tag size excluding header } - { Extended data } - FileSize: Integer; { File size (bytes) } - Frame: array [1..ID3V2_FRAME_COUNT] of string; { Information from frames } - end; - -{ ********************* Auxiliary functions & procedures ******************** } - -function ReadHeader(const FileName: string; var Tag: TagInfo): Boolean; -var - SourceFile: file; - Transferred: Integer; -begin - try - Result := true; - { Set read-access and open file } - AssignFile(SourceFile, FileName); - FileMode := 0; - Reset(SourceFile, 1); - { Read header and get file size } - BlockRead(SourceFile, Tag, 10, Transferred); - Tag.FileSize := FileSize(SourceFile); - CloseFile(SourceFile); - { if transfer is not complete } - if Transferred < 10 then Result := false; - except - { Error } - Result := false; - end; -end; - -{ --------------------------------------------------------------------------- } - -function GetTagSize(const Tag: TagInfo): Integer; -begin - { Get total tag size } - Result := - Tag.Size[1] * $200000 + - Tag.Size[2] * $4000 + - Tag.Size[3] * $80 + - Tag.Size[4] + 10; - if Tag.Flags and $10 > 0 then Inc(Result, 10); - if Result > Tag.FileSize then Result := 0; -end; - -{ --------------------------------------------------------------------------- } - -procedure SetTagItem(const ID, Data: string; var Tag: TagInfo); -var - Iterator: Byte; - FrameID: string; -begin - { Set tag item if supported frame found } - for Iterator := 1 to ID3V2_FRAME_COUNT do - begin - if Tag.Version > TAG_VERSION_2_2 then FrameID := ID3V2_FRAME_NEW[Iterator] - else FrameID := ID3V2_FRAME_OLD[Iterator]; - if FrameID = ID then Tag.Frame[Iterator] := Data; - end; -end; - -{ --------------------------------------------------------------------------- } - -function Swap32(const Figure: Integer): Integer; -var - ByteArray: array [1..4] of Byte absolute Figure; -begin - { Swap 4 bytes } - Result := - ByteArray[1] * $1000000 + - ByteArray[2] * $10000 + - ByteArray[3] * $100 + - ByteArray[4]; -end; - -{ --------------------------------------------------------------------------- } - -procedure ReadFramesNew(const FileName: string; var Tag: TagInfo); -var - SourceFile: file; - Frame: FrameHeaderNew; - Data: array [1..250] of Char; - DataPosition, DataSize: Integer; -begin - { Get information from frames (ID3v2.3.x & ID3v2.4.x) } - try - { Set read-access, open file } - AssignFile(SourceFile, FileName); - FileMode := 0; - Reset(SourceFile, 1); - Seek(SourceFile, 10); - while (FilePos(SourceFile) < GetTagSize(Tag)) and (not EOF(SourceFile)) do - begin - FillChar(Data, SizeOf(Data), 0); - { Read frame header and check frame ID } - BlockRead(SourceFile, Frame, 10); - if not (Frame.ID[1] in ['A'..'Z']) then break; - { Note data position and determine significant data size } - DataPosition := FilePos(SourceFile); - if Swap32(Frame.Size) > SizeOf(Data) then DataSize := SizeOf(Data) - else DataSize := Swap32(Frame.Size); - { Read frame data and set tag item if frame supported } - BlockRead(SourceFile, Data, DataSize); - SetTagItem(Frame.ID, Data, Tag); - Seek(SourceFile, DataPosition + Swap32(Frame.Size)); - end; - CloseFile(SourceFile); - except - end; -end; - -{ --------------------------------------------------------------------------- } - -procedure ReadFramesOld(const FileName: string; var Tag: TagInfo); -var - SourceFile: file; - Frame: FrameHeaderOld; - Data: array [1..250] of Char; - DataPosition, FrameSize, DataSize: Integer; -begin - { Get information from frames (ID3v2.2.x) } - try - { Set read-access, open file } - AssignFile(SourceFile, FileName); - FileMode := 0; - Reset(SourceFile, 1); - Seek(SourceFile, 10); - while (FilePos(SourceFile) < GetTagSize(Tag)) and (not EOF(SourceFile)) do - begin - FillChar(Data, SizeOf(Data), 0); - { Read frame header and check frame ID } - BlockRead(SourceFile, Frame, 6); - if not (Frame.ID[1] in ['A'..'Z']) then break; - { Note data position and determine significant data size } - DataPosition := FilePos(SourceFile); - FrameSize := Frame.Size[1] shl 16 + Frame.Size[2] shl 8 + Frame.Size[3]; - if FrameSize > SizeOf(Data) then DataSize := SizeOf(Data) - else DataSize := FrameSize; - { Read frame data and set tag item if frame supported } - BlockRead(SourceFile, Data, DataSize); - SetTagItem(Frame.ID, Data, Tag); - Seek(SourceFile, DataPosition + FrameSize); - end; - CloseFile(SourceFile); - except - end; -end; - -{ --------------------------------------------------------------------------- } - -function GetContent(const Content1, Content2: string): string; -begin - { Get content preferring the first content } - Result := Trim(Content1); - if Result = '' then Result := Trim(Content2); -end; - -{ --------------------------------------------------------------------------- } - -function ExtractTrack(const TrackString: string): Byte; -var - Index, Value, Code: Integer; -begin - { Extract track from string } - Index := Pos('/', Trim(TrackString)); - if Index = 0 then Val(Trim(TrackString), Value, Code) - else Val(Copy(Trim(TrackString), 1, Index - 1), Value, Code); - if Code = 0 then Result := Value - else Result := 0; -end; - -{ --------------------------------------------------------------------------- } - -function ExtractYear(const YearString, DateString: string): string; -begin - { Extract year from strings } - Result := Trim(YearString); - if Result = '' then Result := Copy(Trim(DateString), 1, 4); -end; - -{ --------------------------------------------------------------------------- } - -function ExtractGenre(const GenreString: string): string; -begin - { Extract genre from string } - Result := Trim(GenreString); - if Pos(')', Result) > 0 then Delete(Result, 1, LastDelimiter(')', Result)); -end; - -{ --------------------------------------------------------------------------- } - -function ExtractComment(const CommentString: string): string; -var - Comment: string; -begin - { Extract comment from string } - Comment := CommentString; - Delete(Comment, 1, 4); - Delete(Comment, 1, Pos(#0, Comment)); - Result := Trim(Comment); -end; - -{ --------------------------------------------------------------------------- } - -function ExtractLink(const LinkString: string): string; -var - Link: string; -begin - { Extract URL link from string } - Link := LinkString; - Delete(Link, 1, 1); - Delete(Link, 1, Pos(#0, Link)); - Result := Trim(Link); -end; - -{ --------------------------------------------------------------------------- } - -procedure BuildHeader(var Tag: TagInfo); -var - Iterator, TagSize: Integer; -begin - { Build tag header } - Tag.ID := ID3V2_ID; - Tag.Version := TAG_VERSION_2_3; - Tag.Revision := 0; - Tag.Flags := 0; - TagSize := 0; - for Iterator := 1 to ID3V2_FRAME_COUNT do - if Tag.Frame[Iterator] <> '' then - Inc(TagSize, Length(Tag.Frame[Iterator]) + 11); - { Convert tag size } - Tag.Size[1] := TagSize div $200000; - Tag.Size[2] := TagSize div $4000; - Tag.Size[3] := TagSize div $80; - Tag.Size[4] := TagSize mod $80; -end; - -{ --------------------------------------------------------------------------- } - -function RebuildFile(const FileName: string; TagData: TStream): Boolean; -var - Tag: TagInfo; - Source, Destination: TFileStream; - BufferName: string; -begin - { Rebuild file with old file data and new tag data (optional) } - Result := false; - if (not FileExists(FileName)) or (FileSetAttr(FileName, 0) <> 0) then exit; - if not ReadHeader(FileName, Tag) then exit; - if (TagData = nil) and (Tag.ID <> ID3V2_ID) then exit; - try - { Create file streams } - BufferName := FileName + '~'; - Source := TFileStream.Create(FileName, fmOpenRead or fmShareExclusive); - Destination := TFileStream.Create(BufferName, fmCreate); - { Copy data blocks } - if Tag.ID = ID3V2_ID then Source.Seek(GetTagSize(Tag), soFromBeginning); - if TagData <> nil then Destination.CopyFrom(TagData, 0); - Destination.CopyFrom(Source, Source.Size - Source.Position); - { Free resources } - Source.Free; - Destination.Free; - { Replace old file and delete temporary file } - if (DeleteFile(FileName)) and (RenameFile(BufferName, FileName)) then - Result := true - else - raise Exception.Create(''); - except - { Access error } - if FileExists(BufferName) then DeleteFile(BufferName); - end; -end; - -{ --------------------------------------------------------------------------- } - -function SaveTag(const FileName: string; Tag: TagInfo): Boolean; -var - TagData: TStringStream; - Iterator, FrameSize: Integer; -begin - { Build and write tag header and frames to stream } - TagData := TStringStream.Create(''); - BuildHeader(Tag); - TagData.Write(Tag, 10); - for Iterator := 1 to ID3V2_FRAME_COUNT do - if Tag.Frame[Iterator] <> '' then - begin - TagData.WriteString(ID3V2_FRAME_NEW[Iterator]); - FrameSize := Swap32(Length(Tag.Frame[Iterator]) + 1); - TagData.Write(FrameSize, SizeOf(FrameSize)); - TagData.WriteString(#0#0#0 + Tag.Frame[Iterator]); - end; - { Rebuild file with new tag data } - Result := RebuildFile(FileName, TagData); - TagData.Free; -end; - -{ ********************** Private functions & procedures ********************* } - -procedure TID3v2.FSetTitle(const NewTitle: string); -begin - { Set song title } - FTitle := Trim(NewTitle); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetArtist(const NewArtist: string); -begin - { Set artist name } - FArtist := Trim(NewArtist); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetAlbum(const NewAlbum: string); -begin - { Set album title } - FAlbum := Trim(NewAlbum); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetTrack(const NewTrack: Byte); -begin - { Set track number } - FTrack := NewTrack; -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetYear(const NewYear: string); -begin - { Set release year } - FYear := Trim(NewYear); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetGenre(const NewGenre: string); -begin - { Set genre name } - FGenre := Trim(NewGenre); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetComment(const NewComment: string); -begin - { Set comment } - FComment := Trim(NewComment); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetComposer(const NewComposer: string); -begin - { Set composer name } - FComposer := Trim(NewComposer); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetEncoder(const NewEncoder: string); -begin - { Set encoder name } - FEncoder := Trim(NewEncoder); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetCopyright(const NewCopyright: string); -begin - { Set copyright information } - FCopyright := Trim(NewCopyright); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetLanguage(const NewLanguage: string); -begin - { Set language } - FLanguage := Trim(NewLanguage); -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.FSetLink(const NewLink: string); -begin - { Set URL link } - FLink := Trim(NewLink); -end; - -{ ********************** Public functions & procedures ********************** } - -constructor TID3v2.Create; -begin - { Create object } - inherited; - ResetData; -end; - -{ --------------------------------------------------------------------------- } - -procedure TID3v2.ResetData; -begin - { Reset all variables } - FExists := false; - FVersionID := 0; - FSize := 0; - FTitle := ''; - FArtist := ''; - FAlbum := ''; - FTrack := 0; - FYear := ''; - FGenre := ''; - FComment := ''; - FComposer := ''; - FEncoder := ''; - FCopyright := ''; - FLanguage := ''; - FLink := ''; -end; - -{ --------------------------------------------------------------------------- } - -function TID3v2.ReadFromFile(const FileName: string): Boolean; -var - Tag: TagInfo; -begin - { Reset data and load header from file to variable } - ResetData; - Result := ReadHeader(FileName, Tag); - { Process data if loaded and header valid } - if (Result) and (Tag.ID = ID3V2_ID) then - begin - FExists := true; - { Fill properties with header data } - FVersionID := Tag.Version; - FSize := GetTagSize(Tag); - { Get information from frames if version supported } - if (FVersionID in [TAG_VERSION_2_2..TAG_VERSION_2_4]) and (FSize > 0) then - begin - if FVersionID > TAG_VERSION_2_2 then ReadFramesNew(FileName, Tag) - else ReadFramesOld(FileName, Tag); - FTitle := GetContent(Tag.Frame[1], Tag.Frame[15]); - FArtist := GetContent(Tag.Frame[2], Tag.Frame[14]); - FAlbum := GetContent(Tag.Frame[3], Tag.Frame[16]); - FTrack := ExtractTrack(Tag.Frame[4]); - FYear := ExtractYear(Tag.Frame[5], Tag.Frame[13]); - FGenre := ExtractGenre(Tag.Frame[6]); - FComment := ExtractComment(Tag.Frame[7]); - FComposer := Trim(Tag.Frame[8]); - FEncoder := Trim(Tag.Frame[9]); - FCopyright := Trim(Tag.Frame[10]); - FLanguage := Trim(Tag.Frame[11]); - FLink := ExtractLink(Tag.Frame[12]); - end; - end; -end; - -{ --------------------------------------------------------------------------- } - -function TID3v2.SaveToFile(const FileName: string): Boolean; -var - Tag: TagInfo; -begin - { Prepare tag data and save to file } - FillChar(Tag, SizeOf(Tag), 0); - Tag.Frame[1] := FTitle; - Tag.Frame[2] := FArtist; - Tag.Frame[3] := FAlbum; - if FTrack > 0 then Tag.Frame[4] := IntToStr(FTrack); - Tag.Frame[5] := FYear; - Tag.Frame[6] := FGenre; - if FComment <> '' then Tag.Frame[7] := 'eng' + #0 + FComment; - Tag.Frame[8] := FComposer; - Tag.Frame[9] := FEncoder; - Tag.Frame[10] := FCopyright; - Tag.Frame[11] := FLanguage; - if FLink <> '' then Tag.Frame[12] := #0 + FLink; - Result := SaveTag(FileName, Tag); -end; - -{ --------------------------------------------------------------------------- } - -function TID3v2.RemoveFromFile(const FileName: string): Boolean; -begin - { Remove tag from file } - Result := RebuildFile(FileName, nil); -end; - -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Info.txt b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Info.txt deleted file mode 100644 index 85b5077..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Info.txt +++ /dev/null @@ -1,32 +0,0 @@ -ID3v2.pas -Tested with Borland Delphi 3,4,5,6 - -{ *************************************************************************** } -{ } -{ Audio Tools Library (Freeware) } -{ Class TID3v2 - for manipulating with ID3v2 tags } -{ } -{ Copyright (c) 2001,2002 by Jurgen Faul } -{ E-mail: jfaul@gmx.de } -{ http://jfaul.de/atl } -{ } -{ Version 1.4 (24 March 2002) } -{ - Reading support for ID3v2.2.x & ID3v2.4.x tags } -{ } -{ Version 1.3 (16 February 2002) } -{ - Fixed bug with property Comment } -{ - Added info: composer, encoder, copyright, language, link } -{ } -{ Version 1.2 (17 October 2001) } -{ - Writing support for ID3v2.3.x tags } -{ - Fixed bug with track number detection } -{ - Fixed bug with tag reading } -{ } -{ Version 1.1 (31 August 2001) } -{ - Added public procedure ResetData } -{ } -{ Version 1.0 (14 August 2001) } -{ - Reading support for ID3v2.3.x tags } -{ - Tag info: title, artist, album, track, year, genre, comment } -{ } -{ *************************************************************************** } \ No newline at end of file diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Main.dfm b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Main.dfm deleted file mode 100644 index 544b7beca5b506c671e1c04081bb9a44655da51e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6378 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 0 then TrackEdit.Text := IntToStr(FileTag.Track); - YearEdit.Text := FileTag.Year; - GenreEdit.Text := FileTag.Genre; - CommentEdit.Text := FileTag.Comment; - ComposerEdit.Text := FileTag.Composer; - EncoderEdit.Text := FileTag.Encoder; - CopyrightEdit.Text := FileTag.Copyright; - LanguageEdit.Text := FileTag.Language; - LinkEdit.Text := FileTag.Link; - end - else - { Tag not found } - TagExistsValue.Text := 'No' - else - { Read error } - ShowMessage('Can not read tag from the file: ' + FileList.FileName) - else - { File does not exist } - ShowMessage('The file does not exist: ' + FileList.FileName); -end; - -procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); -begin - { Free memory } - FileTag.Free; -end; - -procedure TMainForm.SaveButtonClick(Sender: TObject); -var - Value, Code: Integer; -begin - { Prepare tag data } - FileTag.Title := TitleEdit.Text; - FileTag.Artist := ArtistEdit.Text; - FileTag.Album := AlbumEdit.Text; - Val(TrackEdit.Text, Value, Code); - if (Code = 0) and (Value > 0) then FileTag.Track := Value - else FileTag.Track := 0; - FileTag.Year := YearEdit.Text; - FileTag.Genre := GenreEdit.Text; - FileTag.Comment := CommentEdit.Text; - FileTag.Composer := ComposerEdit.Text; - FileTag.Encoder := EncoderEdit.Text; - FileTag.Copyright := CopyrightEdit.Text; - FileTag.Language := LanguageEdit.Text; - FileTag.Link := LinkEdit.Text; - { Save tag data } - if (not FileExists(FileList.FileName)) or - (not FileTag.SaveToFile(FileList.FileName)) then - ShowMessage('Can not save tag to the file: ' + FileList.FileName); - FileListChange(Self); -end; - -procedure TMainForm.RemoveButtonClick(Sender: TObject); -begin - { Delete tag data } - if (FileExists(FileList.FileName)) and - (FileTag.RemoveFromFile(FileList.FileName)) then ClearAll - else ShowMessage('Can not remove tag from the file: ' + FileList.FileName); -end; - -procedure TMainForm.CloseButtonClick(Sender: TObject); -begin - { Exit } - Close; -end; - -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.cfg b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.cfg deleted file mode 100644 index dc18277..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.cfg +++ /dev/null @@ -1,35 +0,0 @@ --$A8 --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$YD --$Z1 --cg --AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; --H+ --W+ --M --$M16384,1048576 --K$00400000 --LE"c:\program files\borland\delphi6\Projects\Bpl" --LN"c:\program files\borland\delphi6\Projects\Bpl" diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.dof b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.dof deleted file mode 100644 index 216ddb6..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.dof +++ /dev/null @@ -1,96 +0,0 @@ -[FileVersion] -Version=6.0 -[Compiler] -A=8 -B=0 -C=1 -D=1 -E=0 -F=0 -G=1 -H=1 -I=1 -J=0 -K=0 -L=1 -M=0 -N=1 -O=1 -P=1 -Q=0 -R=0 -S=0 -T=0 -U=0 -V=1 -W=0 -X=1 -Y=1 -Z=1 -ShowHints=1 -ShowWarnings=1 -UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; -[Linker] -MapFile=0 -OutputObjs=0 -ConsoleApp=1 -DebugInfo=0 -RemoteSymbols=0 -MinStackSize=16384 -MaxStackSize=1048576 -ImageBase=4194304 -ExeDescription= -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages=vcl;rtl;dbrtl;adortl;vcldb;vclx;bdertl;vcldbx;ibxpress;dsnap;cds;bdecds;qrpt;teeui;teedb;tee;dss;teeqr;visualclx;visualdbclx;dsnapcrba;dsnapcon;VclSmp;vclshlctrls;vclie;xmlrtl;inet;inetdbbde;inetdbxpress;inetdb;nmfast;webdsnap;websnap;dbexpress;dbxcds;indy;dclOffice2k -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams= -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang= -RootDir= -[Version Info] -IncludeVerInfo=0 -AutoIncBuild=0 -MajorVer=1 -MinorVer=0 -Release=0 -Build=0 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1031 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=1.0.0.0 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=1.0.0.0 -Comments= -[HistoryLists\hlUnitAliases] -Count=1 -Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; -[HistoryLists\hlUnitOutputDirectory] -Count=1 -Item0=DCU -[HistoryLists\hlOutputDirectorry] -Count=1 -Item0=Data diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.dpr b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.dpr deleted file mode 100644 index e6ad934..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Test; - -uses - Forms, - Main in 'Main.pas' {MainForm}, - ID3v2 in 'ID3v2.pas'; - -{$R *.res} - -begin - Application.Initialize; - Application.Title := 'ID3v2 Test'; - Application.CreateForm(TMainForm, MainForm); - Application.Run; -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.res b/MAC_SDK/3rd Party/TMonkey (Delphi)/ID3v2/Test.res deleted file mode 100644 index bf41bf1bd0d10e2ceb94328f70c8ff216cfd98d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3780 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 kHL@%(%o3FP3)3!YByK*qUEqobT6 0) and - (FHeader.Channels > 0); -end; - -{ --------------------------------------------------------------------------- } - -function TMonkey.FGetVersion: string; -begin - { Get encoder version } - if FHeader.VersionID = 0 then Result := '' - else Str(FHeader.VersionID / 1000 : 4 : 2, Result); -end; - -{ --------------------------------------------------------------------------- } - -function TMonkey.FGetCompression: string; -begin - { Get compression level } - Result := MONKEY_COMPRESSION[FHeader.CompressionID div 1000]; -end; - -{ --------------------------------------------------------------------------- } - -function TMonkey.FGetBits: Byte; -begin - { Get number of bits per sample } - if FGetValid then - begin - Result := 16; - if FHeader.Flags and MONKEY_FLAG_8_BIT > 0 then Result := 8; - if FHeader.Flags and MONKEY_FLAG_24_BIT > 0 then Result := 24; - end - else - Result := 0; -end; - -{ --------------------------------------------------------------------------- } - -function TMonkey.FGetChannelMode: string; -begin - { Get channel mode } - Result := MONKEY_MODE[FHeader.Channels]; -end; - -{ --------------------------------------------------------------------------- } - -function TMonkey.FGetPeak: Double; -begin - { Get peak level ratio } - if (FGetValid) and (FHeader.Flags and MONKEY_FLAG_PEAK_LEVEL > 0) then - case FGetBits of - 16: Result := FHeader.PeakLevel / 32768 * 100; - 24: Result := FHeader.PeakLevel / 8388608 * 100; - else Result := FHeader.PeakLevel / 128 * 100; - end - else - Result := 0; -end; - -{ --------------------------------------------------------------------------- } - -function TMonkey.FGetSamplesPerFrame: Integer; -begin - { Get number of samples in a frame } - if FGetValid then - if (FHeader.VersionID >= 3900) or - ((FHeader.VersionID >= 3800) and - (FHeader.CompressionID = MONKEY_COMPRESSION_EXTRA_HIGH)) then - Result := 73728 - else - Result := 9216 - else - Result := 0; -end; - -{ --------------------------------------------------------------------------- } - -function TMonkey.FGetSamples: Integer; -begin - { Get number of samples } - if FGetValid then - Result := (FHeader.Frames - 1) * FGetSamplesPerFrame + FHeader.FinalSamples - else - Result := 0; -end; - -{ --------------------------------------------------------------------------- } - -function TMonkey.FGetDuration: Double; -begin - { Get song duration } - if FGetValid then Result := FGetSamples / FHeader.SampleRate - else Result := 0; -end; - -{ --------------------------------------------------------------------------- } - -function TMonkey.FGetRatio: Double; -begin - { Get compression ratio } - if FGetValid then - Result := FFileLength / - (FGetSamples * FHeader.Channels * FGetBits / 8 + 44) * 100 - else - Result := 0; -end; - -{ ********************** Public functions & procedures ********************** } - -constructor TMonkey.Create; -begin - { Create object } - inherited; - FID3v1 := TID3v1.Create; - FID3v2 := TID3v2.Create; - FAPEtag := TAPEtag.Create; - FResetData; -end; - -{ --------------------------------------------------------------------------- } - -destructor TMonkey.Destroy; -begin - { Destroy object } - FID3v1.Free; - FID3v2.Free; - FAPEtag.Free; - inherited; -end; - -{ --------------------------------------------------------------------------- } - -function TMonkey.ReadFromFile(const FileName: string): Boolean; -var - SourceFile: file; -begin - try - { Reset data and search for file tag } - FResetData; - if (not FID3v1.ReadFromFile(FileName)) or - (not FID3v2.ReadFromFile(FileName)) or - (not FAPEtag.ReadFromFile(FileName)) then raise Exception.Create(''); - { Set read-access, open file and get file length } - AssignFile(SourceFile, FileName); - FileMode := 0; - Reset(SourceFile, 1); - FFileLength := FileSize(SourceFile); - { Read Monkey's Audio header data } - Seek(SourceFile, ID3v2.Size); - BlockRead(SourceFile, FHeader, SizeOf(FHeader)); - if FHeader.Flags and MONKEY_FLAG_PEAK_LEVEL = 0 then - FHeader.PeakLevel := 0; - if FHeader.Flags and MONKEY_FLAG_SEEK_ELEMENTS = 0 then - FHeader.SeekElements := 0; - CloseFile(SourceFile); - Result := true; - except - FResetData; - Result := false; - end; -end; - -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.cfg b/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.cfg deleted file mode 100644 index dc18277..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.cfg +++ /dev/null @@ -1,35 +0,0 @@ --$A8 --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$YD --$Z1 --cg --AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; --H+ --W+ --M --$M16384,1048576 --K$00400000 --LE"c:\program files\borland\delphi6\Projects\Bpl" --LN"c:\program files\borland\delphi6\Projects\Bpl" diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.dof b/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.dof deleted file mode 100644 index 216ddb6..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.dof +++ /dev/null @@ -1,96 +0,0 @@ -[FileVersion] -Version=6.0 -[Compiler] -A=8 -B=0 -C=1 -D=1 -E=0 -F=0 -G=1 -H=1 -I=1 -J=0 -K=0 -L=1 -M=0 -N=1 -O=1 -P=1 -Q=0 -R=0 -S=0 -T=0 -U=0 -V=1 -W=0 -X=1 -Y=1 -Z=1 -ShowHints=1 -ShowWarnings=1 -UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; -[Linker] -MapFile=0 -OutputObjs=0 -ConsoleApp=1 -DebugInfo=0 -RemoteSymbols=0 -MinStackSize=16384 -MaxStackSize=1048576 -ImageBase=4194304 -ExeDescription= -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages=vcl;rtl;dbrtl;adortl;vcldb;vclx;bdertl;vcldbx;ibxpress;dsnap;cds;bdecds;qrpt;teeui;teedb;tee;dss;teeqr;visualclx;visualdbclx;dsnapcrba;dsnapcon;VclSmp;vclshlctrls;vclie;xmlrtl;inet;inetdbbde;inetdbxpress;inetdb;nmfast;webdsnap;websnap;dbexpress;dbxcds;indy;dclOffice2k -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams= -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang= -RootDir= -[Version Info] -IncludeVerInfo=0 -AutoIncBuild=0 -MajorVer=1 -MinorVer=0 -Release=0 -Build=0 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1031 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=1.0.0.0 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=1.0.0.0 -Comments= -[HistoryLists\hlUnitAliases] -Count=1 -Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; -[HistoryLists\hlUnitOutputDirectory] -Count=1 -Item0=DCU -[HistoryLists\hlOutputDirectorry] -Count=1 -Item0=Data diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.dpr b/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.dpr deleted file mode 100644 index 729fecf..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.dpr +++ /dev/null @@ -1,18 +0,0 @@ -program Test; - -uses - Forms, - Main in 'Main.pas' {MainForm}, - Monkey in 'Monkey.pas', - ID3v1 in '..\ID3v1\ID3v1.pas', - ID3v2 in '..\ID3v2\ID3v2.pas', - APEtag in '..\APEtag\APEtag.pas'; - -{$R *.res} - -begin - Application.Initialize; - Application.Title := 'Monkey Test'; - Application.CreateForm(TMainForm, MainForm); - Application.Run; -end. diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.res b/MAC_SDK/3rd Party/TMonkey (Delphi)/Monkey/Test.res deleted file mode 100644 index 1ce496d085d8fc299deb9603aafc38a537e67933..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3780 zcmZQzU|>*SU|{(FAA&)AWSqeYlV@i5|DO>oB_P1g0%kBUFlaC^FbF`+U}WHc2t$-1 z*l>OW149D?14Batgkop_F&PdVIKXh=&H;uGrRQ{_lc>MQZ$oZecFya3MhAscM;0qpx-2W;Jt^Yk3 z=KjxN*!q70!`c5^@C6UUw*M*&hyHsooco`{aO?jBhG+k`;0qpx|Nm7O{{Q!2`2RnL z;s5^$4F5suaR(2>|7|J^{||XE{6Ck&@c-5XhX2pD;0qpx|G6p*|64s6{?E-}_`h`m z!~e5e@T49FhW{!m4F5em82;zvF#Mk|f#Lraka`h@SOz(U8U_u9*$hSuyBKU3ZZfzr zd|(J=_^*=7@ZY1A;eXCthW`_`GW_3imcfoeiy@Z5o}q>zgkd&ACc`d3T+V-nTNC~>Jlpc0L4?7ML5?AoL4%=&!H8itgAKzj1~-PA4517k7;;tq zGqigAXPBGwpJD5S{|slh{AXZeV`C5!5@L{-muJw?(P6N(v}AB~b!7+&3Sx+lk7vlq z$ziCds9 z|5y>qe+f2<;j!XN#k+U!B9tpCD!#t^8gBe!Ma7rjUVnq}Up{`R`10E~82_cJs_IL{ zmvHwzR(+-lHeVH@0VI#iXL$Meu__2aq`^*j3<6*lgn0S#CDd*I`xzMivokRKV`gCZ z!_2_&gPDQh0|>J-Fnr*L;0OE+3=?&;H~Z{FZi z`0VLZMMXu$m+!DEc=-$@3sUe5n}U~M&0r;Ou~_j8rW>RJ(*PvhAR90&c(w_o4~C&7 zFeARGr$fu{ed;+vNsVHkdk<~}aPXK!F~Ao>}q|K7b+e2Fao z6y5rlid;zYXu25~UcOX(3YLHQOzGLPr>KTAFfhD)2Dbn0+h_Og-Ft>+I7I&C8^yOz zpFVwd?-{z~Ao-^t_q}}i?c2*|-@c*gfA{j;)3=IGpDI54_U+rZr~kj9h0QZ1ZY6Nw zK;*xn%D?1NQ&Usp0x5Xz=z6qjxW28L(vpP{A7|6p*S{{R05`~UwL z)PUum|Bk3=H=F7#QmRKVbg<{|Ed3|3CQu|NmqEUx|T%!2r}Y{LjbW%izf1 u$>7J}$>7Z3&)^636axcty9U%~VPX&v0MQ%_px!7WgMtEt2Wk_6T0#H`L}pt6 diff --git a/MAC_SDK/3rd Party/TMonkey (Delphi)/Readme.txt b/MAC_SDK/3rd Party/TMonkey (Delphi)/Readme.txt deleted file mode 100644 index 1d9e267..0000000 --- a/MAC_SDK/3rd Party/TMonkey (Delphi)/Readme.txt +++ /dev/null @@ -1,5 +0,0 @@ -TMonkey Delphi Class for analyzing APE files - -Sumbitted by Jurgen Faul ( jfaul@gmx.de ) - -(note: this does not directly use the MAC SDK, so it is not guaranteed to work with future APE files) \ No newline at end of file diff --git a/MAC_SDK/Analyze/Sample 1/Sample 1.cpp b/MAC_SDK/Analyze/Sample 1/Sample 1.cpp deleted file mode 100644 index 0b43b89..0000000 --- a/MAC_SDK/Analyze/Sample 1/Sample 1.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/*************************************************************************************** -Analyze - Sample 1 -Copyright (C) 2000-2001 by Matthew T. Ashland All Rights Reserved. -Feel free to use this code in any way that you like. - -This example opens an APE file and displays some basic information about it. To use it, -just type Sample 1.exe followed by a file name and it'll display information about that -file. - -Notes for use in a new project: - -you need to include "MACLib.lib" in the included libraries list - -life will be easier if you set the [MAC SDK]\\Shared directory as an include - directory and an additional library input path in the project settings - -set the runtime library to "Mutlithreaded" - -WARNING: - -This class driven system for using Monkey's Audio is still in development, so - I can't make any guarantees that the classes and libraries won't change before - everything gets finalized. Use them at your own risk. -***************************************************************************************/ - -// includes -#include "all.h" -#include "stdio.h" -#include "maclib.h" -#include "apetag.h" - -int main(int argc, char* argv[]) -{ - /////////////////////////////////////////////////////////////////////////////// - // error check the command line parameters - /////////////////////////////////////////////////////////////////////////////// - if (argc != 2) - { - printf("~~~Improper Usage~~~\r\n\r\n"); - printf("Usage Example: Sample 1.exe 'c:\\1.ape'\r\n\r\n"); - return 0; - } - - /////////////////////////////////////////////////////////////////////////////// - // variable declares - /////////////////////////////////////////////////////////////////////////////// - int nRetVal = 0; // generic holder for return values - char cTempBuffer[256]; ZeroMemory(&cTempBuffer[0], 256); // generic buffer for string stuff - char * pFilename = argv[1]; // the file to open - IAPEDecompress * pAPEDecompress = NULL; // APE interface - - /////////////////////////////////////////////////////////////////////////////// - // open the file and error check - /////////////////////////////////////////////////////////////////////////////// - pAPEDecompress = CreateIAPEDecompress(pFilename, &nRetVal); - if (pAPEDecompress == NULL) - { - printf("Error opening APE file. (error code %d)\r\n\r\n", nRetVal); - return 0; - } - - /////////////////////////////////////////////////////////////////////////////// - // display some information about the file - /////////////////////////////////////////////////////////////////////////////// - printf("Displaying information about '%s':\r\n\r\n", pFilename); - - // file format information - printf("File Format:\r\n"); - printf("\tVersion: %.2f\r\n", float(pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION)) / float(1000)); - switch (pAPEDecompress->GetInfo(APE_INFO_COMPRESSION_LEVEL)) - { - case COMPRESSION_LEVEL_FAST: printf("\tCompression level: Fast\r\n\r\n"); break; - case COMPRESSION_LEVEL_NORMAL: printf("\tCompression level: Normal\r\n\r\n"); break; - case COMPRESSION_LEVEL_HIGH: printf("\tCompression level: High\r\n\r\n"); break; - case COMPRESSION_LEVEL_EXTRA_HIGH: printf("\tCompression level: Extra High\r\n\r\n"); break; - } - - // audio format information - printf("Audio Format:\r\n"); - printf("\tSamples per second: %d\r\n", pAPEDecompress->GetInfo(APE_INFO_SAMPLE_RATE)); - printf("\tBits per sample: %d\r\n", pAPEDecompress->GetInfo(APE_INFO_BITS_PER_SAMPLE)); - printf("\tNumber of channels: %d\r\n", pAPEDecompress->GetInfo(APE_INFO_CHANNELS)); - printf("\tPeak level: %d\r\n\r\n", pAPEDecompress->GetInfo(APE_INFO_PEAK_LEVEL)); - - // size and duration information - printf("Size and Duration:\r\n"); - printf("\tLength of file (s): %d\r\n", pAPEDecompress->GetInfo(APE_INFO_LENGTH_MS) / 1000); - printf("\tFile Size (kb): %d\r\n\r\n", pAPEDecompress->GetInfo(APE_INFO_APE_TOTAL_BYTES) / 1024); - - // tag information - printf("Tag Information:\r\n"); - - CAPETag * pAPETag = (CAPETag *) pAPEDecompress->GetInfo(APE_INFO_TAG); - BOOL bHasID3Tag = pAPETag->GetHasID3Tag(); - BOOL bHasAPETag = pAPETag->GetHasAPETag(); - - if (bHasID3Tag || bHasAPETag) - { - // iterate through all the tag fields - BOOL bFirst = TRUE; - CAPETagField * pTagField; - while (pAPETag->GetNextTagField(bFirst, &pTagField)) - { - bFirst = FALSE; - - // output the tag field properties (don't output huge fields like images, etc.) - if (pTagField->GetFieldValueSize() > 128) - { - printf("\t%s: --- too much data to display ---\r\n", pTagField->GetFieldName()); - } - else - { - printf("\t%s: %s\r\n", pTagField->GetFieldName(), pTagField->GetFieldValue()); - } - } - } - else - { - printf("\tNot tagged\r\n\r\n"); - } - - /////////////////////////////////////////////////////////////////////////////// - // cleanup (just delete the object - /////////////////////////////////////////////////////////////////////////////// - delete pAPEDecompress; - - /////////////////////////////////////////////////////////////////////////////// - // quit - /////////////////////////////////////////////////////////////////////////////// - return 0; -} diff --git a/MAC_SDK/Analyze/Sample 1/Sample 1.dsp b/MAC_SDK/Analyze/Sample 1/Sample 1.dsp deleted file mode 100644 index 2483420..0000000 --- a/MAC_SDK/Analyze/Sample 1/Sample 1.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Sample 1" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=Sample 1 - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Sample 1.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Sample 1.mak" CFG="Sample 1 - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Sample 1 - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "Sample 1 - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Sample 1 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\Shared" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib maclib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Shared" - -!ELSEIF "$(CFG)" == "Sample 1 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\Shared" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib maclib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Shared" - -!ENDIF - -# Begin Target - -# Name "Sample 1 - Win32 Release" -# Name "Sample 1 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=".\Sample 1.cpp" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\Shared\APEInfo.h -# End Source File -# End Group -# End Target -# End Project diff --git a/MAC_SDK/Compress/Sample 1/Sample 1.cpp b/MAC_SDK/Compress/Sample 1/Sample 1.cpp deleted file mode 100644 index a907b8e..0000000 --- a/MAC_SDK/Compress/Sample 1/Sample 1.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************************** -Compress - Sample 1 -Copyright (C) 2000-2001 by Matthew T. Ashland All Rights Reserved. -Feel free to use this code in any way that you like. - -This example illustrates using MACLib.lib to create an APE file by encoding some -random data. - -The IAPECompress interface fully supports on-the-fly encoding. To use on- -the-fly encoding, be sure to tell the encoder to create the proper WAV header on -decompression. Also, you need to specify the absolute maximum audio bytes that will -get encoded. (trying to encode more than the limit set on Start() will cause failure) -This maximum is used to allocates space in the seek table at the front of the file. Currently, -it takes around 8k per hour of CD music, so it isn't a big deal to allocate more than -needed. You can also specify MAX_AUDIO_BYTES_UNKNOWN to allocate as much space as possible. (2 GB) - -Notes for use in a new project: - -you need to include "MACLib.lib" in the included libraries list - -life will be easier if you set the [MAC SDK]\\Shared directory as an include - directory and an additional library input path in the project settings - -set the runtime library to "Mutlithreaded" - -WARNING: - -This class driven system for using Monkey's Audio is still in development, so - I can't make any guarantees that the classes and libraries won't change before - everything gets finalized. Use them at your own risk -***************************************************************************************/ - -// includes -#include -#include -#include "stdio.h" -#include "all.h" -#include "MACLib.h" - -/*************************************************************************************** -Main (the main function) -***************************************************************************************/ -int main(int argc, char* argv[]) -{ - /////////////////////////////////////////////////////////////////////////////// - // variable declares - /////////////////////////////////////////////////////////////////////////////// - int nAudioBytes = 1048576*10; - const char cOutputFile[MAX_PATH] = "c:\\Noise.ape"; - - printf("Creating file: %s\n", cOutputFile); - - /////////////////////////////////////////////////////////////////////////////// - // create and start the encoder - /////////////////////////////////////////////////////////////////////////////// - - // set the input WAV format - WAVEFORMATEX wfeAudioFormat; FillWaveFormatEx(&wfeAudioFormat, 44100, 16, 2); - - // create the encoder interface - IAPECompress * pAPECompress = CreateIAPECompress(); - - // start the encoder - int nRetVal = pAPECompress->Start(cOutputFile, &wfeAudioFormat, nAudioBytes, - COMPRESSION_LEVEL_HIGH, NULL, CREATE_WAV_HEADER_ON_DECOMPRESSION); - - if (nRetVal != 0) - { - SAFE_DELETE(pAPECompress) - printf("Error starting encoder.\n"); - return -1; - } - - /////////////////////////////////////////////////////////////////////////////// - // pump through and feed the encoder audio data (white noise for the sample) - /////////////////////////////////////////////////////////////////////////////// - int nAudioBytesLeft = nAudioBytes; - - while (nAudioBytesLeft > 0) - { - /////////////////////////////////////////////////////////////////////////////// - // NOTE: we're locking the buffer used internally by MAC and copying the data - // directly into it... however, you could also use the AddData(...) command - // to avoid the added complexity of locking and unlocking - // the buffer (but it may be a little slower ) - /////////////////////////////////////////////////////////////////////////////// - - // lock the compression buffer - int nBufferBytesAvailable = 0; - unsigned char * pBuffer = pAPECompress->LockBuffer(&nBufferBytesAvailable); - - // fill the buffer with white noise - int nNoiseBytes = min(nBufferBytesAvailable, nAudioBytesLeft); - for (int z = 0; z < nNoiseBytes; z++) - { - pBuffer[z] = rand() % 255; - } - - // unlock the buffer and let it get processed - int nRetVal = pAPECompress->UnlockBuffer(nNoiseBytes, TRUE); - if (nRetVal != 0) - { - printf("Error Encoding Frame (error: %d)\n", nRetVal); - break; - } - - // update the audio bytes left - nAudioBytesLeft -= nNoiseBytes; - } - - /////////////////////////////////////////////////////////////////////////////// - // finalize the file (could append a tag, or WAV terminating data) - /////////////////////////////////////////////////////////////////////////////// - if (pAPECompress->Finish(NULL, 0, 0) != 0) - { - printf("Error finishing encoder.\n"); - } - - /////////////////////////////////////////////////////////////////////////////// - // clean up and quit - /////////////////////////////////////////////////////////////////////////////// - SAFE_DELETE(pAPECompress) - printf("Done.\n"); - return 0; -} \ No newline at end of file diff --git a/MAC_SDK/Compress/Sample 1/Sample 1.dsp b/MAC_SDK/Compress/Sample 1/Sample 1.dsp deleted file mode 100644 index d69463c..0000000 --- a/MAC_SDK/Compress/Sample 1/Sample 1.dsp +++ /dev/null @@ -1,106 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Sample 1" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=Sample 1 - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Sample 1.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Sample 1.mak" CFG="Sample 1 - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Sample 1 - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "Sample 1 - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Sample 1 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\Shared" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib maclib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Shared" - -!ELSEIF "$(CFG)" == "Sample 1 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\Shared" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib maclib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Shared" - -!ENDIF - -# Begin Target - -# Name "Sample 1 - Win32 Release" -# Name "Sample 1 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=".\Sample 1.cpp" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\Shared\All.h -# End Source File -# Begin Source File - -SOURCE=..\..\Shared\MAC.h -# End Source File -# End Group -# End Target -# End Project diff --git a/MAC_SDK/Compress/Sample 2/Sample 2.cpp b/MAC_SDK/Compress/Sample 2/Sample 2.cpp deleted file mode 100644 index d454b1f..0000000 --- a/MAC_SDK/Compress/Sample 2/Sample 2.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/*************************************************************************************** -Compress - Sample 2 -Copyright (C) 2000-2002 by Matthew T. Ashland All Rights Reserved. -Feel free to use this code in any way that you like. - -This example illustrates dynamic linkage to MACDll.dll to create an APE file using -on-the-fly encoding. - -The IAPECompress interface fully supports on-the-fly encoding. To use on- -the-fly encoding, be sure to tell the encoder to create the proper WAV header on -decompression. Also, you need to specify the absolute maximum audio bytes that will -get encoded. (trying to encode more than the limit set on Start() will cause failure) -This maximum is used to allocates space in the seek table at the front of the file. Currently, -it takes around 8k per hour of CD music, so it isn't a big deal to allocate more than -needed. You can also specify MAX_AUDIO_BYTES_UNKNOWN to allocate as much space as possible. (2 GB) - -Notes for use in a new project: - -life will be easier if you set the [MAC SDK]\\Shared directory as an include - directory and an additional library input path in the project settings - -set the runtime library to "Mutlithreaded" - -WARNING: - -This class driven system for using Monkey's Audio is still in development, so - I can't make any guarantees that the classes and libraries won't change before - everything gets finalized. Use them at your own risk -***************************************************************************************/ - -// includes -#include -#include -#include "stdio.h" -#include "all.h" -#include "MACDll.h" - -/*************************************************************************************** -MAC_DLL structure (holds function pointers) -***************************************************************************************/ -struct MAC_COMPRESS_DLL -{ - // APECompress functions - proc_APECompress_Create Create; - proc_APECompress_Destroy Destroy; - proc_APECompress_Start Start; - proc_APECompress_AddData AddData; - proc_APECompress_Finish Finish; -}; - -/*************************************************************************************** -GetFunctions - helper that gets the function addresses for the functions we need -***************************************************************************************/ -int GetFunctions(HMODULE hMACDll, MAC_COMPRESS_DLL * pMACDll) -{ - // clear - memset(pMACDll, 0, sizeof(MAC_COMPRESS_DLL)); - - // load the functions - if (hMACDll != NULL) - { - pMACDll->Create = (proc_APECompress_Create) GetProcAddress(hMACDll, "c_APECompress_Create"); - pMACDll->Destroy = (proc_APECompress_Destroy) GetProcAddress(hMACDll, "c_APECompress_Destroy"); - pMACDll->Start = (proc_APECompress_Start) GetProcAddress(hMACDll, "c_APECompress_Start"); - pMACDll->AddData = (proc_APECompress_AddData) GetProcAddress(hMACDll, "c_APECompress_AddData"); - pMACDll->Finish = (proc_APECompress_Finish) GetProcAddress(hMACDll, "c_APECompress_Finish"); - } - - // error check - if ((pMACDll->Create == NULL) || - (pMACDll->Destroy == NULL) || - (pMACDll->Start == NULL) || - (pMACDll->AddData == NULL) || - (pMACDll->Finish == NULL)) - { - return -1; - } - - return 0; -} - -/*************************************************************************************** -Version checks the dll / interface -***************************************************************************************/ -int VersionCheckInterface(HMODULE hMACDll) -{ - int nRetVal = -1; - proc_GetInterfaceCompatibility GetInterfaceCompatibility = (proc_GetInterfaceCompatibility) GetProcAddress(hMACDll, "GetInterfaceCompatibility"); - if (GetInterfaceCompatibility) - { - nRetVal = GetInterfaceCompatibility(MAC_VERSION_NUMBER, TRUE, NULL); - } - - return nRetVal; -} - -/*************************************************************************************** -Fill a WAVEFORMATEX structure -***************************************************************************************/ -int FillWaveFormatExStructure(WAVEFORMATEX *pWaveFormatEx, int nSampleRate, int nBitsPerSample, int nChannels) -{ - pWaveFormatEx->cbSize = 0; - pWaveFormatEx->nSamplesPerSec = nSampleRate; - pWaveFormatEx->wBitsPerSample = nBitsPerSample; - pWaveFormatEx->nChannels = nChannels; - pWaveFormatEx->wFormatTag = 1; - - pWaveFormatEx->nBlockAlign = (pWaveFormatEx->wBitsPerSample / 8) * pWaveFormatEx->nChannels; - pWaveFormatEx->nAvgBytesPerSec = pWaveFormatEx->nBlockAlign * pWaveFormatEx->nSamplesPerSec; - - return 0; -} - - -/*************************************************************************************** -Main (the main function) -***************************************************************************************/ -int main(int argc, char* argv[]) -{ - /////////////////////////////////////////////////////////////////////////////// - // variable declares - /////////////////////////////////////////////////////////////////////////////// - int nTotalAudioBytes = 1048576; - const char cOutputFile[MAX_PATH] = "c:\\Noise.ape"; - int nRetVal; - - printf("Creating file: %s\n", cOutputFile); - - /////////////////////////////////////////////////////////////////////////////// - // load MACDll.dll and get the functions - /////////////////////////////////////////////////////////////////////////////// - - // load the DLL - HMODULE hMACDll = LoadLibrary("MACDll.dll"); - if (hMACDll == NULL) - return -1; - - // always check the interface version (so we don't crash if something changed) - if (VersionCheckInterface(hMACDll) != 0) - { - FreeLibrary(hMACDll); - return -1; - } - - // get the functions - MAC_COMPRESS_DLL MACDll; - if (GetFunctions(hMACDll, &MACDll) != 0) - { - FreeLibrary(hMACDll); - return -1; - } - - /////////////////////////////////////////////////////////////////////////////// - // create and start the encoder - /////////////////////////////////////////////////////////////////////////////// - - // set the input WAV format - WAVEFORMATEX wfeAudioFormat; FillWaveFormatExStructure(&wfeAudioFormat, 44100, 16, 2); - - // create the encoder interface - APE_COMPRESS_HANDLE hAPECompress = MACDll.Create(&nRetVal); - if (hAPECompress == NULL) - { - printf("Error creating encoder (error code: %d)\r\n", nRetVal); - FreeLibrary(hMACDll); - return -1; - } - - // start the encoder - nRetVal = MACDll.Start(hAPECompress, cOutputFile, &wfeAudioFormat, nTotalAudioBytes, - COMPRESSION_LEVEL_HIGH, NULL, CREATE_WAV_HEADER_ON_DECOMPRESSION); - - if (nRetVal != 0) - { - printf("Error starting encoder.\n"); - MACDll.Destroy(hAPECompress); - FreeLibrary(hMACDll); - return -1; - } - - /////////////////////////////////////////////////////////////////////////////// - // pump through and feed the encoder audio data (white noise for the sample) - /////////////////////////////////////////////////////////////////////////////// - int nAudioBytesLeft = nTotalAudioBytes; - unsigned char cBuffer[1024]; - - while (nAudioBytesLeft > 0) - { - // fill the buffer with white noise - for (int z = 0; z < 1024; z++) - cBuffer[z] = rand() % 255; - - // give the data to MAC - // (we can safely add any amount, but of course larger chunks take longer to process) - int nBytesToAdd = min(1024, nAudioBytesLeft); - nRetVal = MACDll.AddData(hAPECompress, &cBuffer[0], nBytesToAdd); - - if (nRetVal != ERROR_SUCCESS) - printf("Encoding error (error code: %d)\r\n", nRetVal); - - // update the audio bytes left - nAudioBytesLeft -= nBytesToAdd; - } - - /////////////////////////////////////////////////////////////////////////////// - // finalize the file (could append a tag, or WAV terminating data) - /////////////////////////////////////////////////////////////////////////////// - if (MACDll.Finish(hAPECompress, NULL, 0, 0) != 0) - { - printf("Error finishing encoder.\n"); - } - - /////////////////////////////////////////////////////////////////////////////// - // clean up and quit - /////////////////////////////////////////////////////////////////////////////// - MACDll.Destroy(hAPECompress); - FreeLibrary(hMACDll); - printf("Done.\n"); - return 0; -} \ No newline at end of file diff --git a/MAC_SDK/Compress/Sample 2/Sample 2.dsp b/MAC_SDK/Compress/Sample 2/Sample 2.dsp deleted file mode 100644 index 5ebc0b4..0000000 --- a/MAC_SDK/Compress/Sample 2/Sample 2.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Sample 2" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=Sample 2 - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Sample 2.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Sample 2.mak" CFG="Sample 2 - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Sample 2 - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "Sample 2 - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Sample 2 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\..\Shared" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "Sample 2 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\Shared" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "Sample 2 - Win32 Release" -# Name "Sample 2 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=".\Sample 2.cpp" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/MAC_SDK/Decompress/Sample 1/Sample 1.cpp b/MAC_SDK/Decompress/Sample 1/Sample 1.cpp deleted file mode 100644 index 18e5b2f..0000000 --- a/MAC_SDK/Decompress/Sample 1/Sample 1.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************************** -Decompress - Sample 1 -Copyright (C) 2000-2001 by Matthew T. Ashland All Rights Reserved. -Feel free to use this code in any way that you like. - -This example illustrates using MACDLib.lib and the simple IAPESimple class to verify -or decompress a file. (verify and decompress work the same, except that verify doesn't -have an output file) Also, shows how to use a callback to display the progress. - -General Notes: - -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. - -Notes for use in a new project: - -you need to include "MACLib.lib" in the included libraries list - -life will be easier if you set the [MAC SDK]\\Shared directory as an include - directory and an additional library input path in the project settings - -set the runtime library to "Mutlithreaded" - -WARNING: - -This class driven system for using Monkey's Audio is still in development, so - I can't make any guarantees that the classes and libraries won't change before - everything gets finalized. Use them at your own risk. -***************************************************************************************/ - -// includes -#include -#include "stdio.h" -#include "all.h" -#include "maclib.h" - -// global variables (evil... but alright for a simple sample) -unsigned __int32 g_nInitialTickCount; - -/*************************************************************************************** -Progress callback -***************************************************************************************/ -void CALLBACK ProgressCallback(int nPercentageDone) -{ - double dProgress = double(nPercentageDone) / 1000; - double dElapsedMS = (GetTickCount() - g_nInitialTickCount); - - double dSecondsRemaining = (((dElapsedMS * 100) / dProgress) - dElapsedMS) / 1000; - printf("Progress: %.1f%% (%.1f seconds remaining) \r", dProgress, dSecondsRemaining); -} - -/*************************************************************************************** -Main (the main function) -***************************************************************************************/ -int main(int argc, char* argv[]) -{ - /////////////////////////////////////////////////////////////////////////////// - // error check the command line parameters - /////////////////////////////////////////////////////////////////////////////// - if (argc != 2) - { - printf("~~~Improper Usage~~~\n\n"); - printf("Usage Example: Sample 1.exe \"c:\\1.ape\"\n\n"); - return 0; - } - - /////////////////////////////////////////////////////////////////////////////// - // variable declares - /////////////////////////////////////////////////////////////////////////////// - int nPercentageDone = 0; //the percentage done... continually updated by the decoder - int nKillFlag = 0; //the kill flag for controlling the decoder - int nRetVal = 0; //generic holder for return values - char * pFilename = argv[1]; //the file to open - - /////////////////////////////////////////////////////////////////////////////// - // attempt to verify the file - /////////////////////////////////////////////////////////////////////////////// - - // set the start time and display the starting message - g_nInitialTickCount = GetTickCount(); - printf("Verifying '%s'...\n", pFilename); - - // do the verify (call unmac.dll) - nRetVal = VerifyFile(pFilename, &nPercentageDone, ProgressCallback, &nKillFlag); - - // process the return value - if (nRetVal == 0) - printf("\nPassed...\n"); - else - printf("\nFailed (error: %d)\n", nRetVal); - - /////////////////////////////////////////////////////////////////////////////// - // quit - /////////////////////////////////////////////////////////////////////////////// - return 0; -} \ No newline at end of file diff --git a/MAC_SDK/Decompress/Sample 1/Sample 1.dsp b/MAC_SDK/Decompress/Sample 1/Sample 1.dsp deleted file mode 100644 index 2f07507..0000000 --- a/MAC_SDK/Decompress/Sample 1/Sample 1.dsp +++ /dev/null @@ -1,110 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Sample 1" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=Sample 1 - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Sample 1.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Sample 1.mak" CFG="Sample 1 - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Sample 1 - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "Sample 1 - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Sample 1 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\Shared" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib maclib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Shared" - -!ELSEIF "$(CFG)" == "Sample 1 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\Shared" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib maclib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Shared" - -!ENDIF - -# Begin Target - -# Name "Sample 1 - Win32 Release" -# Name "Sample 1 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=".\Sample 1.cpp" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\Shared\All.h -# End Source File -# Begin Source File - -SOURCE=..\..\Shared\APEInfo.h -# End Source File -# Begin Source File - -SOURCE=..\..\Shared\UnMAC.h -# End Source File -# End Group -# End Target -# End Project diff --git a/MAC_SDK/Decompress/Sample 1/Sample 1.vcproj b/MAC_SDK/Decompress/Sample 1/Sample 1.vcproj deleted file mode 100644 index 6cd4ad1..0000000 --- a/MAC_SDK/Decompress/Sample 1/Sample 1.vcproj +++ /dev/null @@ -1,460 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MAC_SDK/Decompress/Sample 2/Sample 2.cpp b/MAC_SDK/Decompress/Sample 2/Sample 2.cpp deleted file mode 100644 index ff28883..0000000 --- a/MAC_SDK/Decompress/Sample 2/Sample 2.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************************** -Decompress - Sample 2 -Copyright (C) 2000-2001 by Matthew T. Ashland All Rights Reserved. -Feel free to use this code in any way that you like. - -This example illustrates using MACLib.lib to do decoding and seeking of an APE file. -The library manages all seeking and buffering, so you simply seek -to a location and ask for the amount of data required. (Seek() and GetData()) - -GetData will return the amount requested unless you're at the end of the file. (in -which case it returns everything up to the end) It's typically a good idea to check -the return value of each decode. A value other than ERROR_SUCCESS (0) means errors -were encountered. In these cases, the decoder will do the best job it can to keep -returning valid data. (corrupt data will be converted to silence) - -General Notes: - -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. - -Notes for use in a new project: - -you need to include "MACLib.lib" in the included libraries list - -life will be easier if you set the [MAC SDK]\\Shared directory as an include - directory and an additional library input path in the project settings - -set the runtime library to "Mutlithreaded" - -WARNING: - -This class driven system for using Monkey's Audio is still in development, so - I can't make any guarantees that the classes and libraries won't change before - everything gets finalized. Use them at your own risk -***************************************************************************************/ - -// includes -#include -#include "stdio.h" -#include "all.h" -#include "maclib.h" - -/*************************************************************************************** -Main (the main function) -***************************************************************************************/ -int main(int argc, char* argv[]) -{ - /////////////////////////////////////////////////////////////////////////////// - // error check the command line parameters - /////////////////////////////////////////////////////////////////////////////// - if (argc != 2) - { - printf("~~~Improper Usage~~~\r\n\r\n"); - printf("Usage Example: Sample 2.exe \"c:\\1.ape\"\r\n\r\n"); - return 0; - } - - /////////////////////////////////////////////////////////////////////////////// - // variable declares - /////////////////////////////////////////////////////////////////////////////// - int nPercentageDone = 0; // the percentage done... continually updated by the decoder - int nKillFlag = 0; // the kill flag for controlling the decoder - int nRetVal = 0; // generic holder for return values - char * pFilename = argv[1]; // the file to open - - /////////////////////////////////////////////////////////////////////////////// - // open the APE file - /////////////////////////////////////////////////////////////////////////////// - IAPEDecompress * pAPEDecompress = CreateIAPEDecompress(L"E:\\Music\\Steve Hackett\\Steve Hackett - Wild Orchids (2006)\\Steve Hackett - Wild Orchids (2006).ape" , &nRetVal); - if (pAPEDecompress == NULL) - { - printf("Error opening APE file (error code: %d)\r\n", nRetVal); - return -1; - } - - /////////////////////////////////////////////////////////////////////////////// - // allocate space for the raw decompressed data - /////////////////////////////////////////////////////////////////////////////// - char * pRawData = new char [1024 * pAPEDecompress->GetInfo(APE_INFO_BLOCK_ALIGN)]; - if (pRawData == NULL) { return -1; } - - /////////////////////////////////////////////////////////////////////////////// - // ask for data at a a few random locations and display the sum of 1024 blocks - /////////////////////////////////////////////////////////////////////////////// - for (int z = 0; z < 160; z++) - { - // figure a random location in the file and seek to it - int nRandomBlock = rand() % (pAPEDecompress->GetInfo(APE_DECOMPRESS_TOTAL_BLOCKS) - 1024); - nRetVal = pAPEDecompress->Seek(nRandomBlock); - if (nRetVal != 0) { - printf("Seek error (%d)\r\n", nRetVal); - return -1; - } - - // decompress 1024 blocks from that location - int nBlocksRetrieved; - nRetVal = pAPEDecompress->GetData(pRawData, 1024, &nBlocksRetrieved); - if (nRetVal != ERROR_SUCCESS) - { - printf("Decoding error (%d)\r\n", nRetVal); - } - - // figure the sum of the decoded data - int nBytesRetrieved = nBlocksRetrieved * pAPEDecompress->GetInfo(APE_INFO_BLOCK_ALIGN); - int nSum = 0; - for (int x = 0; x < nBytesRetrieved; x++) - { - nSum += pRawData[x]; - } - - // display the sum - printf("Block / Sum = %.4d / %d\r\n", nRandomBlock, nSum); - - } - - /////////////////////////////////////////////////////////////////////////////// - // clean-up and quit - /////////////////////////////////////////////////////////////////////////////// - delete pAPEDecompress; - return 0; -} \ No newline at end of file diff --git a/MAC_SDK/Decompress/Sample 2/Sample 2.dsp b/MAC_SDK/Decompress/Sample 2/Sample 2.dsp deleted file mode 100644 index 91aa5c2..0000000 --- a/MAC_SDK/Decompress/Sample 2/Sample 2.dsp +++ /dev/null @@ -1,114 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Sample 2" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=Sample 2 - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Sample 2.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Sample 2.mak" CFG="Sample 2 - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Sample 2 - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "Sample 2 - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Sample 2 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\Shared" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib maclib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Shared" - -!ELSEIF "$(CFG)" == "Sample 2 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\Shared" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib maclib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Shared" - -!ENDIF - -# Begin Target - -# Name "Sample 2 - Win32 Release" -# Name "Sample 2 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=".\Sample 2.cpp" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\Shared\All.h -# End Source File -# Begin Source File - -SOURCE=..\..\Shared\APEInfo.h -# End Source File -# Begin Source File - -SOURCE=..\..\Shared\MACDll.h -# End Source File -# Begin Source File - -SOURCE=..\..\Shared\UnMAC.h -# End Source File -# End Group -# End Target -# End Project diff --git a/MAC_SDK/Decompress/Sample 2/Sample 2.vcproj b/MAC_SDK/Decompress/Sample 2/Sample 2.vcproj deleted file mode 100644 index c7e6ea4..0000000 --- a/MAC_SDK/Decompress/Sample 2/Sample 2.vcproj +++ /dev/null @@ -1,461 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MAC_SDK/Decompress/Sample 3/Sample 3.cpp b/MAC_SDK/Decompress/Sample 3/Sample 3.cpp deleted file mode 100644 index 8ec781a..0000000 --- a/MAC_SDK/Decompress/Sample 3/Sample 3.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/*************************************************************************************** -Decompress - Sample 3 -Copyright (C) 2000-2001 by Matthew T. Ashland All Rights Reserved. -Feel free to use this code in any way that you like. - -This example illustrates dynamic linkage to MACDll.dll to decompress a whole file -and display a simple checksum. (see Sample 1 and Sample 2 for more info) - -General Notes: - -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. - -Notes for use in a new project: - -life will be easier if you set the [MAC SDK]\\Shared directory as an include - directory and an additional library input path in the project settings - -set the runtime library to "Mutlithreaded" - -WARNING: - -This class driven system for using Monkey's Audio is still in development, so - I can't make any guarantees that the classes and libraries won't change before - everything gets finalized. Use them at your own risk -***************************************************************************************/ - -// includes -#include -#include "stdio.h" -#include "MACDll.h" - -/*************************************************************************************** -MAC_DLL structure (holds function pointers) -***************************************************************************************/ -struct MAC_DLL -{ - // APEDecompress functions - proc_APEDecompress_Create Create; - proc_APEDecompress_Destroy Destroy; - proc_APEDecompress_GetData GetData; - proc_APEDecompress_Seek Seek; - proc_APEDecompress_GetInfo GetInfo; -}; - -/*************************************************************************************** -GetFunctions - helper that gets the function addresses for the functions we need -***************************************************************************************/ -int GetFunctions(HMODULE hMACDll, MAC_DLL * pMACDll) -{ - // clear - memset(pMACDll, 0, sizeof(MAC_DLL)); - - // load the functions - if (hMACDll != NULL) - { - pMACDll->Create = (proc_APEDecompress_Create) GetProcAddress(hMACDll, "c_APEDecompress_Create"); - pMACDll->Destroy = (proc_APEDecompress_Destroy) GetProcAddress(hMACDll, "c_APEDecompress_Destroy"); - pMACDll->GetData = (proc_APEDecompress_GetData) GetProcAddress(hMACDll, "c_APEDecompress_GetData"); - pMACDll->Seek = (proc_APEDecompress_Seek) GetProcAddress(hMACDll, "c_APEDecompress_Seek"); - pMACDll->GetInfo = (proc_APEDecompress_GetInfo) GetProcAddress(hMACDll, "c_APEDecompress_GetInfo"); - } - - // error check - if ((pMACDll->Create == NULL) || - (pMACDll->Destroy == NULL) || - (pMACDll->GetData == NULL) || - (pMACDll->Seek == NULL) || - (pMACDll->GetInfo == NULL)) - { - return -1; - } - - return 0; -} - -/*************************************************************************************** -Version checks the dll / interface -***************************************************************************************/ -int VersionCheckInterface(HMODULE hMACDll) -{ - int nRetVal = -1; - proc_GetInterfaceCompatibility GetInterfaceCompatibility = (proc_GetInterfaceCompatibility) GetProcAddress(hMACDll, "GetInterfaceCompatibility"); - if (GetInterfaceCompatibility) - { - nRetVal = GetInterfaceCompatibility(MAC_VERSION_NUMBER, TRUE, NULL); - } - - return nRetVal; -} - -/*************************************************************************************** -Main (the main function) -***************************************************************************************/ -int main(int argc, char* argv[]) -{ - /////////////////////////////////////////////////////////////////////////////// - // error check the command line parameters - /////////////////////////////////////////////////////////////////////////////// - if (argc != 2) - { - printf("~~~Improper Usage~~~\r\n\r\n"); - printf("Usage Example: Sample 3.exe \"c:\\1.ape\"\r\n\r\n"); - return 0; - } - - /////////////////////////////////////////////////////////////////////////////// - // variable declares - /////////////////////////////////////////////////////////////////////////////// - int nRetVal = 0; // generic holder for return values - char * pFilename = argv[1]; // the file to open - - /////////////////////////////////////////////////////////////////////////////// - // load MACDll.dll and get the functions - /////////////////////////////////////////////////////////////////////////////// - - // load the DLL - HMODULE hMACDll = LoadLibrary("MACDll.dll"); - if (hMACDll == NULL) - return -1; - - // always check the interface version (so we don't crash if something changed) - if (VersionCheckInterface(hMACDll) != 0) - { - FreeLibrary(hMACDll); - return -1; - } - - // get the functions - MAC_DLL MACDll; - if (GetFunctions(hMACDll, &MACDll) != 0) - { - FreeLibrary(hMACDll); - return -1; - } - - /////////////////////////////////////////////////////////////////////////////// - // create the APEDecompress object for the file - /////////////////////////////////////////////////////////////////////////////// - - APE_DECOMPRESS_HANDLE hAPEDecompress = MACDll.Create(pFilename, &nRetVal); - if (hAPEDecompress == NULL) - { - printf("Error opening APE file (error code: %d)\r\n", nRetVal); - FreeLibrary(hMACDll); - return -1; - } - - /////////////////////////////////////////////////////////////////////////////// - // calculate a byte-level checksum of the whole file - /////////////////////////////////////////////////////////////////////////////// - - // make a buffer to hold 1024 blocks of audio data - int nBlockAlign = MACDll.GetInfo(hAPEDecompress, APE_INFO_BLOCK_ALIGN, 0, 0); - unsigned char * pBuffer = new unsigned char [1024 * nBlockAlign]; - - // loop through the whole file - int nTotalBlocks = MACDll.GetInfo(hAPEDecompress, APE_DECOMPRESS_TOTAL_BLOCKS, 0, 0); - int nBlocksRetrieved = 1; - int nTotalBlocksRetrieved = 0; - unsigned int nChecksum = 0; - while (nBlocksRetrieved > 0) - { - // try to decompress 1024 blocks - nRetVal = MACDll.GetData(hAPEDecompress, (char *) pBuffer, 1024, &nBlocksRetrieved); - if (nRetVal != 0) - printf("Decompression error (continuing with checksum, but file is probably corrupt)\r\n"); - - // calculate the sum (byte-by-byte) - for (int z = 0; z < (nBlockAlign * nBlocksRetrieved); z++) - { - nChecksum += abs(int(pBuffer[z])); - } - - nTotalBlocksRetrieved += nBlocksRetrieved; - - // output the progress - printf("Progress: %.1f%% \r", (float(nTotalBlocksRetrieved) * float(100)) / float(max(nTotalBlocks, 1.0))); - } - - delete [] pBuffer; - - // output the result - printf("Progress: done. \r\n"); - printf("Stupid-style Checksum: 0x%X\r\n", nChecksum); - - /////////////////////////////////////////////////////////////////////////////// - // clean-up and quit - /////////////////////////////////////////////////////////////////////////////// - MACDll.Destroy(hAPEDecompress); - FreeLibrary(hMACDll); - return 0; -} \ No newline at end of file diff --git a/MAC_SDK/Decompress/Sample 3/Sample 3.dsp b/MAC_SDK/Decompress/Sample 3/Sample 3.dsp deleted file mode 100644 index bd15e25..0000000 --- a/MAC_SDK/Decompress/Sample 3/Sample 3.dsp +++ /dev/null @@ -1,115 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Sample 3" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=Sample 3 - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Sample 3.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Sample 3.mak" CFG="Sample 3 - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Sample 3 - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "Sample 3 - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Sample 3 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\Shared\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "Sample 3 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\Shared\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib maclib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Shared\\" - -!ENDIF - -# Begin Target - -# Name "Sample 3 - Win32 Release" -# Name "Sample 3 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=".\Sample 3.cpp" - -!IF "$(CFG)" == "Sample 3 - Win32 Release" - -# ADD CPP /MT - -!ELSEIF "$(CFG)" == "Sample 3 - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/MAC_SDK/Decompress/Sample 3/Sample 3.vcproj b/MAC_SDK/Decompress/Sample 3/Sample 3.vcproj deleted file mode 100644 index edecf7e..0000000 --- a/MAC_SDK/Decompress/Sample 3/Sample 3.vcproj +++ /dev/null @@ -1,451 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MAC_SDK/Shared/APETag.h b/MAC_SDK/Shared/APETag.h deleted file mode 100644 index eecd8b7..0000000 --- a/MAC_SDK/Shared/APETag.h +++ /dev/null @@ -1,293 +0,0 @@ -#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 m_spFieldNameUTF16; - CSmartPtr 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 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 - diff --git a/MAC_SDK/Shared/All.h b/MAC_SDK/Shared/All.h deleted file mode 100644 index 27192cd..0000000 --- a/MAC_SDK/Shared/All.h +++ /dev/null @@ -1,235 +0,0 @@ -#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 - #define ENABLE_ASSEMBLY -#endif - -#define NO_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 NO_IO_HEADER_FILE "WinFileIO.h" - #define NO_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/Shared/IO.h b/MAC_SDK/Shared/IO.h deleted file mode 100644 index 63b4d7f..0000000 --- a/MAC_SDK/Shared/IO.h +++ /dev/null @@ -1,49 +0,0 @@ -#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/Shared/MACDll.h b/MAC_SDK/Shared/MACDll.h deleted file mode 100644 index 7940017..0000000 --- a/MAC_SDK/Shared/MACDll.h +++ /dev/null @@ -1,99 +0,0 @@ -/***************************************************************************************** -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 diff --git a/MAC_SDK/Shared/MACLib.h b/MAC_SDK/Shared/MACLib.h deleted file mode 100644 index 5a70cd3..0000000 --- a/MAC_SDK/Shared/MACLib.h +++ /dev/null @@ -1,452 +0,0 @@ -/***************************************************************************************** -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) - ////////////////////////////////////////////////////////////////////////////////////////////// - -#ifdef IO_CLASS_NAME - 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; -#endif - - 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 diff --git a/MAC_SDK/Shared/SmartPtr.h b/MAC_SDK/Shared/SmartPtr.h deleted file mode 100644 index c9bb9be..0000000 --- a/MAC_SDK/Shared/SmartPtr.h +++ /dev/null @@ -1,89 +0,0 @@ -#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/Console/Console.cpp b/MAC_SDK/Source/Console/Console.cpp deleted file mode 100644 index f08a790..0000000 --- a/MAC_SDK/Source/Console/Console.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/*************************************************************************************** -MAC Console Frontend (MAC.exe) - -Pretty simple and straightforward console front end. If somebody ever wants to add -more functionality like tagging, auto-verify, etc., that'd be excellent. - -Copyrighted (c) 2000 - 2003 Matthew T. Ashland. All Rights Reserved. -***************************************************************************************/ -#include "All.h" -#include -#include "GlobalFunctions.h" -#include "MACLib.h" -#include "CharacterHelper.h" - -// defines -#define COMPRESS_MODE 0 -#define DECOMPRESS_MODE 1 -#define VERIFY_MODE 2 -#define CONVERT_MODE 3 -#define UNDEFINED_MODE -1 - -// global variables -TICK_COUNT_TYPE g_nInitialTickCount = 0; - -/*************************************************************************************** -Displays the proper usage for MAC.exe -***************************************************************************************/ -void DisplayProperUsage(FILE * pFile) -{ - fprintf(pFile, "Proper Usage: [EXE] [Input File] [Output File] [Mode]\n\n"); - - fprintf(pFile, "Modes: \n"); - fprintf(pFile, " Compress (fast): '-c1000'\n"); - fprintf(pFile, " Compress (normal): '-c2000'\n"); - fprintf(pFile, " Compress (high): '-c3000'\n"); - fprintf(pFile, " Compress (extra high): '-c4000'\n"); - fprintf(pFile, " Compress (insane): '-c5000'\n"); - fprintf(pFile, " Decompress: '-d'\n"); - fprintf(pFile, " Verify: '-v'\n"); - fprintf(pFile, " Convert: '-nXXXX'\n\n"); - - fprintf(pFile, "Examples:\n"); - fprintf(pFile, " Compress: mac.exe \"Metallica - One.wav\" \"Metallica - One.ape\" -c2000\n"); - fprintf(pFile, " Decompress: mac.exe \"Metallica - One.ape\" \"Metallica - One.wav\" -d\n"); - fprintf(pFile, " Verify: mac.exe \"Metallica - One.ape\" -v\n"); - fprintf(pFile, " (note: int filenames must be put inside of quotations)\n"); -} - -/*************************************************************************************** -Progress callback -***************************************************************************************/ -void CALLBACK ProgressCallback(int nPercentageDone) -{ - // get the current tick count - TICK_COUNT_TYPE nTickCount; - TICK_COUNT_READ(nTickCount); - - // calculate the progress - double dProgress = nPercentageDone / 1.e5; // [0...1] - double dElapsed = (double) (nTickCount - g_nInitialTickCount) / TICK_COUNT_FREQ; // seconds - double dRemaining = dElapsed * ((1.0 / dProgress) - 1.0); // seconds - - // output the progress - fprintf(stderr, "Progress: %.1f%% (%.1f seconds remaining, %.1f seconds total) \r", - dProgress * 100, dRemaining, dElapsed); -} - -/*************************************************************************************** -Main (the main function) -***************************************************************************************/ -int main(int argc, char * argv[]) -{ - // variable declares - CSmartPtr spInputFilename; CSmartPtr spOutputFilename; - int nRetVal = ERROR_UNDEFINED; - int nMode = UNDEFINED_MODE; - int nCompressionLevel; - int nPercentageDone; - - // output the header - fprintf(stderr, CONSOLE_NAME); - - // make sure there are at least four arguments (could be more for EAC compatibility) - if (argc < 3) - { - DisplayProperUsage(stderr); - exit(-1); - } - - // store the input file - spInputFilename.Assign(GetUTF16FromANSI(argv[1]), TRUE); - - // store the output file - spOutputFilename.Assign(GetUTF16FromANSI(argv[2]), TRUE); - - // verify that the input file exists - if (!FileExists(spInputFilename)) - { - fprintf(stderr, "Input File Not Found...\n\n"); - exit(-1); - } - - // if the output file equals '-v', then use this as the next argument - char cMode[256]; - strcpy(cMode, argv[2]); - - if (_strnicmp(cMode, "-v", 2) != 0) - { - // verify is the only mode that doesn't use at least the third argument - if (argc < 4) - { - DisplayProperUsage(stderr); - exit(-1); - } - - // check for and skip if necessary the -b XXXXXX arguments (3,4) - strcpy(cMode, argv[3]); - } - - // get the mode - nMode = UNDEFINED_MODE; - if (_strnicmp(cMode, "-c", 2) == 0) - nMode = COMPRESS_MODE; - else if (_strnicmp(cMode, "-d", 2) == 0) - nMode = DECOMPRESS_MODE; - else if (_strnicmp(cMode, "-v", 2) == 0) - nMode = VERIFY_MODE; - else if (_strnicmp(cMode, "-n", 2) == 0) - nMode = CONVERT_MODE; - - // error check the mode - if (nMode == UNDEFINED_MODE) - { - DisplayProperUsage(stderr); - exit(-1); - } - - // get and error check the compression level - if (nMode == COMPRESS_MODE || nMode == CONVERT_MODE) - { - nCompressionLevel = atoi(&cMode[2]); - if (nCompressionLevel != 1000 && nCompressionLevel != 2000 && - nCompressionLevel != 3000 && nCompressionLevel != 4000 && - nCompressionLevel != 5000) - { - DisplayProperUsage(stderr); - return -1; - } - } - - // set the initial tick count - TICK_COUNT_READ(g_nInitialTickCount); - - // process - int nKillFlag = 0; - if (nMode == COMPRESS_MODE) - { - char cCompressionLevel[16]; - if (nCompressionLevel == 1000) { strcpy(cCompressionLevel, "fast"); } - if (nCompressionLevel == 2000) { strcpy(cCompressionLevel, "normal"); } - if (nCompressionLevel == 3000) { strcpy(cCompressionLevel, "high"); } - if (nCompressionLevel == 4000) { strcpy(cCompressionLevel, "extra high"); } - if (nCompressionLevel == 5000) { strcpy(cCompressionLevel, "insane"); } - - fprintf(stderr, "Compressing (%s)...\n", cCompressionLevel); - nRetVal = CompressFileW(spInputFilename, spOutputFilename, nCompressionLevel, &nPercentageDone, ProgressCallback, &nKillFlag); - } - else if (nMode == DECOMPRESS_MODE) - { - fprintf(stderr, "Decompressing...\n"); - nRetVal = DecompressFileW(spInputFilename, spOutputFilename, &nPercentageDone, ProgressCallback, &nKillFlag); - } - else if (nMode == VERIFY_MODE) - { - fprintf(stderr, "Verifying...\n"); - nRetVal = VerifyFileW(spInputFilename, &nPercentageDone, ProgressCallback, &nKillFlag); - } - else if (nMode == CONVERT_MODE) - { - fprintf(stderr, "Converting...\n"); - nRetVal = ConvertFileW(spInputFilename, spOutputFilename, nCompressionLevel, &nPercentageDone, ProgressCallback, &nKillFlag); - } - - if (nRetVal == ERROR_SUCCESS) - fprintf(stderr, "\nSuccess...\n"); - else - fprintf(stderr, "\nError: %i\n", nRetVal); - - return nRetVal; -} diff --git a/MAC_SDK/Source/Console/Console.dsp b/MAC_SDK/Source/Console/Console.dsp deleted file mode 100644 index 34d47d1..0000000 --- a/MAC_SDK/Source/Console/Console.dsp +++ /dev/null @@ -1,114 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Console" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=Console - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Console.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Console.mak" CFG="Console - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Console - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "Console - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName ""$/Monkey's Audio/Console", GKAAAAAA" -# PROP Scc_LocalPath "." -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Console - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\MACLib\\" /I "..\Shared\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 maclib.lib kernel32.lib user32.lib gdi32.lib /nologo /subsystem:console /profile /machine:I386 /out:"Release/MAC.exe" /libpath:"..\MACLib\Release" -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=copy Release\MAC.exe C:\MAC\Application\MAC.exe -# End Special Build Tool - -!ELSEIF "$(CFG)" == "Console - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\MACLib\\" /I "..\Shared\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 maclib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/MAC.exe" /pdbtype:sept /libpath:"..\MACLib\Debug" -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=copy Debug\MAC.exe C:\MAC\Application\MAC.exe -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "Console - Win32 Release" -# Name "Console - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\Console.cpp -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\Resource Script.rc" -# End Source File -# Begin Source File - -SOURCE=.\resource.h -# End Source File -# End Group -# End Target -# End Project diff --git a/MAC_SDK/Source/Console/Console.vcproj b/MAC_SDK/Source/Console/Console.vcproj deleted file mode 100644 index a805d0f..0000000 --- a/MAC_SDK/Source/Console/Console.vcproj +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MAC_SDK/Source/Console/Resource Script.rc b/MAC_SDK/Source/Console/Resource Script.rc deleted file mode 100644 index 0dde37d..0000000 --- a/MAC_SDK/Source/Console/Resource Script.rc +++ /dev/null @@ -1,103 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,9,0 - PRODUCTVERSION 3,9,9,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "Console front-end for Monkey's Audio" - VALUE "CompanyName", "Matthew T. Ashland" - VALUE "FileDescription", "Monkey's Audio Console Front-End" - VALUE "FileVersion", "3.99" - VALUE "InternalName", "MAC" - VALUE "LegalCopyright", "Copyright © 2000-2004" - VALUE "OriginalFilename", "MAC.exe" - VALUE "ProductName", "Monkey's Audio" - VALUE "ProductVersion", "3.99" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/MAC_SDK/Source/Console/resource.h b/MAC_SDK/Source/Console/resource.h deleted file mode 100644 index 4876854..0000000 --- a/MAC_SDK/Source/Console/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Resource Script.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/MAC_SDK/Source/Credits.txt b/MAC_SDK/Source/Credits.txt deleted file mode 100644 index 1e09508..0000000 --- a/MAC_SDK/Source/Credits.txt +++ /dev/null @@ -1,25 +0,0 @@ -Source Code Credits: (listed in alphabetical order by first name) - -Chun-Yu Shei: -- cool suggestion for a slightly more optimized GetSaturatedShortFromInt(...) routine - -David Bryant: -- lots of ideas and support from continued discussions - -Florin Ghido: -- planted the seed for a more efficient stereo decorrelator - -Frank Klemm: -- helped with several Linux building issues, APEv2 tags, and MD5 checksums - -Janne Hyvärinen: (case@mobiili.net) -- donated some nice UTF / ANSI conversion code for APE version 2 tagging - -Torgeir Strand Henriksen: (torgshen@stud.iet.hist.no) -- did all the footwork to enable BACKWARDS_COMPATIBILITY without requiring assembly - -Michael Bevin: (support@lossless-audio.com) -- had a good entropy idea for improving entropy coding ( http://www.lossless-audio.com/theory.htm ) - -Igor Janos: (radscorpion@radlight.com) -- wrote the APE DirectShow filter \ No newline at end of file diff --git a/MAC_SDK/Source/History.txt b/MAC_SDK/Source/History.txt deleted file mode 100644 index b8134a0..0000000 --- a/MAC_SDK/Source/History.txt +++ /dev/null @@ -1,79 +0,0 @@ -History: - -Monkey's Audio 3.99 Update 4 - -1. Fixed: Decoder could erroneously report a CRC error on the last frame of some files. - -Monkey's Audio 3.99 Update 3 - -1. Changed: Worked on making data types more standard / cross-platform friendly. -2. Changed: Switched code from tab-based to space based. (may still be some out-of-whack formatting) -3. Fixed: Building ID3 tags could cause a crash. -4. Fixed: APL builder treated the last part of a CUE time as a hundreth of a second instead of as a frame. (1 / 75 of a second) -5. Fixed: File Info dialog used by Winamp plugin wouldn't accept / save Unicode tag values properly. -6. Fixed: APL files could output noise or silence at the end of the file in some cases. - -Monkey's Audio 3.99 Update 2 - -1. Fixed: Possible buffer overflow attack weakness in APE tagging code. -2. Fixed: MACDll.dll was not doing ANSI to Unicode conversions properly. -3. Changed: Added Unicode versions of interface wrappers to MACDll.dll. -4. Changed: Updated Winamp plugin to better handle Unicode. -5. Changed: Removed peak-level normalize from file and Winamp plugin. (newer players can do normalize / replay gain during playback) -6. Changed: Updated Cool Edit filter to 3.99. - -Monkey's Audio 3.99 Update 1 - -1. Fixed: MACDll.dll wasn't working on Win9x / ME systems. -2. Changed: MAC.exe updated to 3.99. - -Monkey's Audio 3.99 - -1. Changed: Decoding engine better at handling corrupt streams / loss of internet connection while playing. -2. Changed: Simplified assembly code building for 3rd party developers. -3. NEW: Improved entropy coder for increased compression. -4. Changed: Removed RKAU support. (since it is no longer commonly used) - -Monkey's Audio 3.98a1 - -1. Changed: Now natively using APE tag version 2 tagging. (updated spec for better streaming and international support) -2. Changed: Using smaller frame sizes with Fast, Normal, and High for faster, smoother seeking. -3. NEW: Added built-in MD5 checking, for super secure, super fast file verification. -4. Changed: Using a new and improved file header format. -5. NEW: Added "Insane" mode for when compression is all that matters. -6. NEW: Introduced new GUI. - - full Unicode support - - few or no dependencies - - multi-thread friendly -- can process multiple files at once - - XML based external plugin architecture - -Monkey's Audio 3.97 (July 7, 2002) - -1. Changed: "Save File List Between Sessions" now on by default in front end. -2. Changed: Replaced usage of "#pragma once" with more non-MS compiler friendly alterternative. -3. NEW: MakeAPL now supports command line APL generation. (pass a .CUE file (no wildcards yet) -- operates in silent mode using existing settings) -4. Changed: Assembly support no longer required for backwards compatibility. (thanks Torgeir Strand Henriksen) -5. Changed: Several non-Windows buildability issues. -6. Changed: Using NASM to compile all assembly code. (aids cross-platform buildability) -7. Changed: Encapsulated the APELink code. -8. Changed: Tags aren't analyzed immediately when opening an http:// or m01p:// stream. -9. Changed: Added more functionality to the APL parser. -10. Changed: Added CreateIAPEDecompressEx2(...) to allow the creation of a ranged decoder. - -Monkey's Audio 3.96 (April 7, 2002) - -1. Fixed: WAV analysis could hang on invalid wav files. -2. Changed: Monkey's Audio would try to analyze files with file extensions not related to Monkey's Audio. -3. NEW: Added APE_DECOMPRESS_AVERAGE_BITRATE field so APL's can report the bitrate for the region they represent. -4. Changed: Improved overall non-Windows build-ability. (MACLib.lib doesn't require to build) -5. Changed: APL parser no longer requires Windows. -6. Fixed: APE tagging code would fail to save tags for files with existing ID3v1 tags. -7. Fixed: MakeAPL would not run on Win95 / 98. -8. Changed: More non-Windows build-ability issues. -9. Changed: Minor assembly optimizations. (like a 2% performance improvement) -10. Changed: MACLib now builds with gcc under Linux. (no backwards compatibility or assembly support yet) -11. Fixed: Bitstream fix / change that may have accounted for decompression failures in extremely rare cases. -12. Changed: Slight NNFilter optimization. (thanks to Chun-Yu Shei) -13. Changed: Turned off "Explorer" by default for the Monkey's Audio GUI. (doesn't work well under XP... will still leave it in for a while) -14. Changed: Included the WavPack 3.93. -15. Changed: Changed the history reporting method. \ No newline at end of file diff --git a/MAC_SDK/Source/License.htm b/MAC_SDK/Source/License.htm deleted file mode 100644 index fe22ad4..0000000 --- a/MAC_SDK/Source/License.htm +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - -Well - - - - -

Monkey's Audio Source Code -License Agreement

-

License Agreement

-

1. The use of any of the Monkey’s Audio source code or any component thereof from another program requires -express written permission from the author of Monkey’s Audio.

-

2. The use of Monkey's Audio or the Monkey's Audio source code for any commercial purposes including, but not -limited to, implementation in shareware packages is strictly prohibited without first obtaining written -permission from the author.

-

3. All code changes and improvements must be -contributed back to the Monkey's Audio project free from restrictions or -royalties for the sake of the common good.

-

4. Although the software has been tested thoroughly, the author is in no way responsible for damages due to -bugs or misuse. 

-

5. If you do not completely agree with all of -the previous stipulations, you must cease using this source code and remove it -from your storage device.

-

 

-

Non-legally Binding License Description

-

The above license is designed to protect both -me, and the Monkey's Audio project.  However, anyone who has ever been kind -enough to request permission to use Monkey's Audio has been granted the right to -do as they please, completely free of charge or royalty.  So, the license -exists not to hinder what considerate people can do with Monkey's Audio, but -instead to protect against the (hopefully few) inconsiderate people.

-

 

-

 

-

All -rights not expressly granted here are reserved by Matthew T. Ashland.

-

 

-

- -All materials and programs copyrighted ©2000-2002 by Matthew T. Ashland -

-

- -All rights reserved. -

- - - - diff --git a/MAC_SDK/Source/MACDll/MACDll.cpp b/MAC_SDK/Source/MACDll/MACDll.cpp deleted file mode 100644 index 80aaef8..0000000 --- a/MAC_SDK/Source/MACDll/MACDll.cpp +++ /dev/null @@ -1,233 +0,0 @@ -#include "MACDll.h" -#include "resource.h" -#include "WinFileIO.h" -#include "APEInfoDialog.h" -#include "WAVInfoDialog.h" -#include "APEDecompress.h" -#include "APECompressCreate.h" -#include "APECompressCore.h" -#include "APECompress.h" -#include "APEInfo.h" -#include "APETag.h" -#include "CharacterHelper.h" - -int __stdcall GetVersionNumber() -{ - return MAC_VERSION_NUMBER; -} - -int __stdcall GetInterfaceCompatibility(int nVersion, BOOL bDisplayWarningsOnFailure, HWND hwndParent) -{ - int nRetVal = 0; - if (nVersion > MAC_VERSION_NUMBER) - { - nRetVal = -1; - if (bDisplayWarningsOnFailure) - { - TCHAR cMessage[1024]; - _stprintf(cMessage, _T("You system does not have a new enough version of Monkey's Audio installed.\n") - _T("Please visit www.monkeysaudio.com for the latest version.\n\n(version %.2f or later required)"), - float(nVersion) / float(1000)); - MessageBox(hwndParent, cMessage, _T("Please Update Monkey's Audio"), MB_OK | MB_ICONINFORMATION); - } - } - else if (nVersion < 3940) - { - nRetVal = -1; - if (bDisplayWarningsOnFailure) - { - TCHAR cMessage[1024]; - _stprintf(cMessage, _T("This program is trying to use an old version of Monkey's Audio.\n") - _T("Please contact the author about updating their support for Monkey's Audio.\n\n") - _T("Monkey's Audio currently installed: %.2f\nProgram is searching for: %.2f"), - float(MAC_VERSION_NUMBER) / float(1000), float(nVersion) / float(1000)); - MessageBox(hwndParent, cMessage, _T("Program Requires Updating"), MB_OK | MB_ICONINFORMATION); - } - } - - return nRetVal; -} - -int __stdcall ShowFileInfoDialog(const str_ansi * pFilename, HWND hwndWindow) -{ - // convert the filename - CSmartPtr spFilename(GetUTF16FromANSI(pFilename), TRUE); - - // make sure the file exists - WIN32_FIND_DATA FindData = { 0 }; - HANDLE hFind = FindFirstFile(spFilename, &FindData); - if (hFind == INVALID_HANDLE_VALUE) - { - MessageBox(hwndWindow, _T("File not found."), _T("File Info"), MB_OK); - return 0; - } - else - { - FindClose(hFind); - } - - // see what type the file is - if ((_tcsicmp(&spFilename[_tcslen(spFilename) - 4], _T(".ape")) == 0) || - (_tcsicmp(&spFilename[_tcslen(spFilename) - 4], _T(".apl")) == 0)) - { - CAPEInfoDialog APEInfoDialog; - APEInfoDialog.ShowAPEInfoDialog(spFilename, GetModuleHandle(_T("MACDll.dll")), (LPCTSTR) IDD_APE_INFO, hwndWindow); - return 0; - } - else if (_tcsicmp(&spFilename[_tcslen(spFilename) - 4], _T(".wav")) == 0) - { - CWAVInfoDialog WAVInfoDialog; - WAVInfoDialog.ShowWAVInfoDialog(spFilename, GetModuleHandle(_T("MACDll.dll")), (LPCTSTR) IDD_WAV_INFO, hwndWindow); - return 0; - } - else - { - MessageBox(hwndWindow, _T("File type not supported. (only .ape, .apl, and .wav files currently supported)"), _T("File Info: Unsupported File Type"), MB_OK); - return 0; - }; -} - -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) -{ - CSmartPtr spFilename(GetUTF16FromANSI(pFilename), TRUE); - - IO_CLASS_NAME FileIO; - if (FileIO.Open(spFilename) != 0) - return -1; - - CAPETag APETag(&FileIO, TRUE); - - if (bClearFirst) - APETag.ClearFields(); - - APETag.SetFieldString(APE_TAG_FIELD_ARTIST, pArtist, TRUE); - APETag.SetFieldString(APE_TAG_FIELD_ALBUM, pAlbum, TRUE); - APETag.SetFieldString(APE_TAG_FIELD_TITLE, pTitle, TRUE); - APETag.SetFieldString(APE_TAG_FIELD_GENRE, pGenre, TRUE); - APETag.SetFieldString(APE_TAG_FIELD_YEAR, pYear, TRUE); - APETag.SetFieldString(APE_TAG_FIELD_COMMENT, pComment, TRUE); - APETag.SetFieldString(APE_TAG_FIELD_TRACK, pTrack, TRUE); - - if (APETag.Save(bUseOldID3) != 0) - { - return -1; - } - - return 0; -} - -int __stdcall GetID3Tag(const str_ansi * pFilename, ID3_TAG * pID3Tag) -{ - CSmartPtr spFilename(GetUTF16FromANSI(pFilename), TRUE); - - IO_CLASS_NAME FileIO; - if (FileIO.Open(spFilename) != 0) - return -1; - - CAPETag APETag(&FileIO, TRUE); - - return APETag.CreateID3Tag(pID3Tag); -} - -int __stdcall RemoveTag(char * pFilename) -{ - CSmartPtr spFilename(GetUTF16FromANSI(pFilename), TRUE); - - int nErrorCode = ERROR_SUCCESS; - CSmartPtr spAPEDecompress(CreateIAPEDecompress(spFilename, &nErrorCode)); - if (spAPEDecompress == NULL) return -1; - GET_TAG(spAPEDecompress)->Remove(FALSE); - return 0; -} - -/***************************************************************************************** -CAPEDecompress wrapper(s) -*****************************************************************************************/ -APE_DECOMPRESS_HANDLE __stdcall c_APEDecompress_Create(const str_ansi * pFilename, int * pErrorCode) -{ - CSmartPtr spFilename(GetUTF16FromANSI(pFilename), TRUE); - return (APE_DECOMPRESS_HANDLE) CreateIAPEDecompress(spFilename, pErrorCode); -} - -APE_DECOMPRESS_HANDLE __stdcall c_APEDecompress_CreateW(const str_utf16 * pFilename, int * pErrorCode) -{ - return (APE_DECOMPRESS_HANDLE) CreateIAPEDecompress(pFilename, pErrorCode); -} - -void __stdcall c_APEDecompress_Destroy(APE_DECOMPRESS_HANDLE hAPEDecompress) -{ - IAPEDecompress * pAPEDecompress = (IAPEDecompress *) hAPEDecompress; - if (pAPEDecompress) - delete pAPEDecompress; -} - -int __stdcall c_APEDecompress_GetData(APE_DECOMPRESS_HANDLE hAPEDecompress, char * pBuffer, int nBlocks, int * pBlocksRetrieved) -{ - return ((IAPEDecompress *) hAPEDecompress)->GetData(pBuffer, nBlocks, pBlocksRetrieved); -} - -int __stdcall c_APEDecompress_Seek(APE_DECOMPRESS_HANDLE hAPEDecompress, int nBlockOffset) -{ - return ((IAPEDecompress *) hAPEDecompress)->Seek(nBlockOffset); -} - -int __stdcall c_APEDecompress_GetInfo(APE_DECOMPRESS_HANDLE hAPEDecompress, APE_DECOMPRESS_FIELDS Field, int nParam1, int nParam2) -{ - return ((IAPEDecompress *) hAPEDecompress)->GetInfo(Field, nParam1, nParam2); -} - -/***************************************************************************************** -CAPECompress wrapper(s) -*****************************************************************************************/ -APE_COMPRESS_HANDLE __stdcall c_APECompress_Create(int * pErrorCode) -{ - return (APE_COMPRESS_HANDLE) CreateIAPECompress(pErrorCode); -} - -void __stdcall c_APECompress_Destroy(APE_COMPRESS_HANDLE hAPECompress) -{ - IAPECompress * pAPECompress = (IAPECompress *) hAPECompress; - if (pAPECompress) - delete pAPECompress; -} - -int __stdcall c_APECompress_Start(APE_COMPRESS_HANDLE hAPECompress, const char * pOutputFilename, const WAVEFORMATEX * pwfeInput, int nMaxAudioBytes, int nCompressionLevel, const void * pHeaderData, int nHeaderBytes) -{ - CSmartPtr spOutputFilename(GetUTF16FromANSI(pOutputFilename), TRUE); - return ((IAPECompress *) hAPECompress)->Start(spOutputFilename, pwfeInput, nMaxAudioBytes, nCompressionLevel, pHeaderData, nHeaderBytes); -} - -int __stdcall c_APECompress_StartW(APE_COMPRESS_HANDLE hAPECompress, const str_utf16 * pOutputFilename, const WAVEFORMATEX * pwfeInput, int nMaxAudioBytes, int nCompressionLevel, const void * pHeaderData, int nHeaderBytes) -{ - return ((IAPECompress *) hAPECompress)->Start(pOutputFilename, pwfeInput, nMaxAudioBytes, nCompressionLevel, pHeaderData, nHeaderBytes); -} - -int __stdcall c_APECompress_AddData(APE_COMPRESS_HANDLE hAPECompress, unsigned char * pData, int nBytes) -{ - return ((IAPECompress *) hAPECompress)->AddData(pData, nBytes); -} - -int __stdcall c_APECompress_GetBufferBytesAvailable(APE_COMPRESS_HANDLE hAPECompress) -{ - return ((IAPECompress *) hAPECompress)->GetBufferBytesAvailable(); -} - -unsigned char * __stdcall c_APECompress_LockBuffer(APE_COMPRESS_HANDLE hAPECompress, int * pBytesAvailable) -{ - return ((IAPECompress *) hAPECompress)->LockBuffer(pBytesAvailable); -} - -int __stdcall c_APECompress_UnlockBuffer(APE_COMPRESS_HANDLE hAPECompress, int nBytesAdded, BOOL bProcess) -{ - return ((IAPECompress *) hAPECompress)->UnlockBuffer(nBytesAdded, bProcess); -} - -int __stdcall c_APECompress_Finish(APE_COMPRESS_HANDLE hAPECompress, unsigned char * pTerminatingData, int nTerminatingBytes, int nWAVTerminatingBytes) -{ - return ((IAPECompress *) hAPECompress)->Finish(pTerminatingData, nTerminatingBytes, nWAVTerminatingBytes); -} - -int __stdcall c_APECompress_Kill(APE_COMPRESS_HANDLE hAPECompress) -{ - return ((IAPECompress *) hAPECompress)->Kill(); -} diff --git a/MAC_SDK/Source/MACDll/MACDll.def b/MAC_SDK/Source/MACDll/MACDll.def deleted file mode 100644 index 9bfc12d..0000000 --- a/MAC_SDK/Source/MACDll/MACDll.def +++ /dev/null @@ -1,38 +0,0 @@ -LIBRARY MACDll - -EXPORTS - - ; basic functions - CompressFile - DecompressFile - ConvertFile - VerifyFile - - ; interface wrappers - c_APEDecompress_Create - c_APEDecompress_Destroy - c_APEDecompress_GetData - c_APEDecompress_Seek - c_APEDecompress_GetInfo - - c_APECompress_Create - c_APECompress_Destroy - c_APECompress_Start - c_APECompress_AddData - c_APECompress_GetBufferBytesAvailable - c_APECompress_LockBuffer - c_APECompress_UnlockBuffer - c_APECompress_Finish - c_APECompress_Kill - - ; helpers / miscellaneous - GetVersionNumber - GetInterfaceCompatibility - ShowFileInfoDialog - RemoveTag - TagFileSimple - GetID3Tag - FillWaveHeader - FillWaveFormatEx - - diff --git a/MAC_SDK/Source/MACDll/MACDll.dsp b/MAC_SDK/Source/MACDll/MACDll.dsp deleted file mode 100644 index a16da73..0000000 --- a/MAC_SDK/Source/MACDll/MACDll.dsp +++ /dev/null @@ -1,160 +0,0 @@ -# Microsoft Developer Studio Project File - Name="MACDll" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=MACDll - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "MACDll.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "MACDll.mak" CFG="MACDll - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "MACDll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "MACDll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName ""$/Monkey's Audio/MACDll", KCAAAAAA" -# PROP Scc_LocalPath "." -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "MACDll - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MACDLL_EXPORTS" /YX /FD /c -# ADD CPP /nologo /G6 /MT /W3 /GX /Ox /Ot /Og /Oi /Ob2 /I "..\MACLib\\" /I "..\Shared\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MACDLL_EXPORTS" /FR /YX /FD /c -# SUBTRACT CPP /Oa -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib maclib.lib /nologo /dll /machine:I386 /libpath:"..\MACLib\Release" -# SUBTRACT LINK32 /profile -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Desc=Performing post build step... -PostBuild_Cmds=copy Release\MACDll.dll c:\Windows\System32\MACDll.dll -# End Special Build Tool - -!ELSEIF "$(CFG)" == "MACDll - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MACDLL_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\MACLib\\" /I "..\Shared\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MACDLL_EXPORTS" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 maclib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"..\MACLib\Debug" -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Desc=Performing post build step... -PostBuild_Cmds=copy Debug\MACDll.dll c:\Windows\System32\MACDll.dll -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "MACDll - Win32 Release" -# Name "MACDll - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\Shared\APEInfoDialog.cpp -# End Source File -# Begin Source File - -SOURCE=.\MACDll.cpp -# End Source File -# Begin Source File - -SOURCE=.\MACDll.def -# End Source File -# Begin Source File - -SOURCE=".\Resource Script.rc" -# End Source File -# Begin Source File - -SOURCE=..\Shared\WAVInfoDialog.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\Shared\APEInfoDialog.h -# End Source File -# Begin Source File - -SOURCE=.\MACDll.h -# End Source File -# Begin Source File - -SOURCE=.\resource.h -# End Source File -# Begin Source File - -SOURCE=..\Shared\WAVInfoDialog.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=".\Monkey Head (1).ico" -# End Source File -# Begin Source File - -SOURCE=".\Monkey Head.ico" -# End Source File -# End Group -# End Target -# End Project diff --git a/MAC_SDK/Source/MACDll/MACDll.h b/MAC_SDK/Source/MACDll/MACDll.h deleted file mode 100644 index 7940017..0000000 --- a/MAC_SDK/Source/MACDll/MACDll.h +++ /dev/null @@ -1,99 +0,0 @@ -/***************************************************************************************** -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 diff --git a/MAC_SDK/Source/MACDll/MACDll.vcproj b/MAC_SDK/Source/MACDll/MACDll.vcproj deleted file mode 100644 index d6cccc4..0000000 --- a/MAC_SDK/Source/MACDll/MACDll.vcproj +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MAC_SDK/Source/MACDll/Monkey Head (1).ico b/MAC_SDK/Source/MACDll/Monkey Head (1).ico deleted file mode 100644 index c04520b4da462932989c329c9dc2fdefcd7fb476..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2238 zcmZQzU}RuqP*7k1gB2VM3}Orn3>pj!3?Lx~29P`lSgwHuOkp877&tgM7#KJN7&tft z7z99AK!AaPLxMp-K!QO+LV|&TLy>_&K#_q%K#@U0LXkm2QISDW5hSL`peUiqps1+H zpsA_Jz#w4Az#w7Bps8udU}y+pTQX>BS~3`du%#t~rKKeUgQ63Ip{5gqp`jClrJ)mp zlamtzgQ6FMrJ)ytrKJ~xlcg7fmzNg#Sj%0 z#lWDM%n;<2%#fU%%)nrn%@F04%@7ro&5)g)&A?z;%#a*Z%urlh%%JI1&0y$M&5#^b z&5#{c%}`xk&A?#U!oc9v!jK)+!cd&t!qCzJ;`cBVC-*QEXZJAl^z<+=I89+-@S4I< zojrwN$`lZL4ns>Z2rp&msb0#kbSa2l%P^&7EyLQiAbKmqoR+N&Teogy@XFrHFsElP z!_uC;414#2=wl2^ryOHgJLMR|v11_m9K*SD=NQ(`xyG<{&NYT>*RC;aU3!mU@6vk= z_wLwAXx??Lo;hVS3MGbH!? zXSlZaKg0k3qj)q7NJ|5-!oXHhSkVc_!Jz$(lk;ZjP2MXl~l`bj@X7ECh0dp*(;qpa}Oom`FWI`_yAzviLz=J~-2WNKo{n-&+#q!t$^ab!vf$-9bM7@~!dMQVXsR%~h#TTzN%hNFbO zEHkPX_?h(FESSV?HT|spY*?JVz1>BTE#YTmkl|Nm;O9^FV`P_LaCX-5){sG%;HD$W zs2X16=b2L!!R_rW!Om{yEsG>CICQx~RxT)>}fu+uK`797*0yz>HfcKb=9fD1pV!gON?c zNCGvLX*0<%*vPAka_|^=s0%X~%Af@g0|SEvgQ&N+hqt#8gFlkVNK8d;XK!zNSq7ZB z%#ewjnb8fGc92Ob%6fdBvh5B&fC|B3(q|L_0*0HZ4L5dZ)H diff --git a/MAC_SDK/Source/MACDll/Monkey Head.ico b/MAC_SDK/Source/MACDll/Monkey Head.ico deleted file mode 100644 index ad58c3469ae5cb531a262b5418a8ea10556fa9eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2238 zcmZQzU}RuqP*7k1gB2VM3}Orn3>pj!3?Lx~29P`lSgwHuOkp877&tgM7#KJN7&tft z7z99AK!AaPLxMp-K!QO+LV|&TLy>_&K#_q%K#@U0LXkm2QISDW5hSL`peUiqps1+H zpsA_Jz#w4Az#w7Bps8udU}y+pTQX>BS~3`du%#t~rKKeUgQ63Ip{5gqp`jClrJ)mp zlamtzgQ6FMrJ)ytrKJ~xlcg7fmzNg#Sj%0 z#lWDM%n;<2%#fU%%)nrn%@F04%@7ro&5)g)&A?z;%#a*Z%urlh%%JI1&0y$M&5#^b z&5#{c%}`xk&A?#U!oc9v!jK)+!cd&t!qCzJ;`cBVC-*QEXZJAl^z<+=I89+-@S4I< zojrwN$`lZL4ns>Z2rp&msb0#kbSa2l%P^&7EyLQiAbKmqoR+N&Teogy@XFrHFsElP z!_uC;414#2=wl2^ryOHgJLMR|v11_m9K*SD=NQ(`xyG<{&NYT>*RC;aU3!mU@6vk= z_wLwAXx??Lo;hVS3MGbH!? zXSlZaKg0k3qj)q7NJ|4)3IiuaVMSXk;!q)eh2Wh0WMh9Q7mada^(g`a6Eq13*McP) zEL&8RuLTi7A-x!aq0&V~jwmuB>ukfcCNeg%$jB>8AH zkRSqEsAdQuNf-H`>1Rs}v__WKL}&%GB#X?EjZXv%A_ynrB87A${R-j;IS|X#x=1J& zEFbL?U6hXze1^tFLir$h14bSeDJcdwkR~K-$g9khUsROo$C6f<&4^|=0|SF0L!fR- zQ3?k?zg3tOFPh&$@|u}0(M7t3#RZ0JZUt!iEetKhUFC(OGC7ipi&JHai%pSiW?*1o zmerSV%RU1PUa6 zc5fLZ8yKB+MD0AxK>CY{tc!|rBt-3zEf81o_V(70@RqeHDvA~>D)Nzaw@22`z$sy* z!N%xe$C6N_%8;Hf#BC;kWIqD~gN2MCgRr`X5f6u`y1Wg843jpJ^-!iigORtlhqt#V z14`&XWf>S4_!(sFy}g~e6%j%xEPn`(2h9Kfe_;Rr{{#R3|G(`2|Np=L FKLBjk^eX@W diff --git a/MAC_SDK/Source/MACDll/Resource Script.rc b/MAC_SDK/Source/MACDll/Resource Script.rc deleted file mode 100644 index 09179f7..0000000 --- a/MAC_SDK/Source/MACDll/Resource Script.rc +++ /dev/null @@ -1,226 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_WAV_INFO, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 195 - TOPMARGIN, 7 - BOTTOMMARGIN, 95 - END - - IDD_APE_INFO, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 242 - TOPMARGIN, 7 - BOTTOMMARGIN, 211 - END -END -#endif // APSTUDIO_INVOKED - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_MONKEY_LEFT ICON "Monkey Head.ico" -IDI_MONKEY_RIGHT ICON "Monkey Head (1).ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_WAV_INFO DIALOG 0, 0, 202, 102 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | - WS_SYSMENU -CAPTION "WAV File Info" -FONT 8, "MS Sans Serif" -BEGIN - ICON IDI_MONKEY_LEFT,IDC_STATIC,2,2,20,20 - ICON IDI_MONKEY_RIGHT,IDC_STATIC,180,0,20,20 - GROUPBOX "Size Info",IDC_STATIC,5,28,93,68 - GROUPBOX "Audio Info",IDC_STATIC,105,28,92,47 - LTEXT "Bits Per Sample:",3002,115,60,78,8,SS_NOPREFIX - LTEXT "Channels:",3001,115,50,78,8,SS_NOPREFIX - LTEXT "Sample Rate:",3000,115,39,78,8,SS_NOPREFIX - LTEXT "Track Length:",2001,15,50,78,8,SS_NOPREFIX - LTEXT "File Size:",2000,15,39,78,8,SS_NOPREFIX - LTEXT "Terminating Bytes:",2004,15,82,78,8,SS_NOPREFIX - LTEXT "Header Bytes:",2003,15,71,78,8,SS_NOPREFIX - LTEXT "Audio Bytes:",2002,15,60,78,8,SS_NOPREFIX - PUSHBUTTON "OK",4000,105,81,92,15 - CTEXT "File Name...",1000,26,2,152,18 -END - -IDD_APE_INFO DIALOG 0, 0, 249, 218 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | - WS_SYSMENU -CAPTION "APE File Info" -FONT 8, "MS Sans Serif" -BEGIN - EDITTEXT 5000,49,99,189,12,ES_AUTOHSCROLL - EDITTEXT 5001,49,115,189,12,ES_AUTOHSCROLL - EDITTEXT 5002,49,131,189,12,ES_AUTOHSCROLL - EDITTEXT 5003,49,147,189,12,ES_AUTOHSCROLL - EDITTEXT 5004,49,163,24,12,ES_AUTOHSCROLL - COMBOBOX 5005,109,163,77,85,CBS_DROPDOWN | CBS_OEMCONVERT | - CBS_SORT | WS_VSCROLL | WS_TABSTOP - EDITTEXT 5006,220,163,18,12,ES_AUTOHSCROLL - PUSHBUTTON "Save Tag",6000,11,195,69,12 - PUSHBUTTON "Remove Tag",6001,90,195,69,12 - PUSHBUTTON "Cancel",6002,169,195,69,12 - ICON IDI_MONKEY_LEFT,IDC_STATIC,3,3,20,20 - ICON IDI_MONKEY_RIGHT,IDC_STATIC,225,3,20,20 - CONTROL "Format Flags:",2002,"Static",SS_LEFTNOWORDWRAP | - SS_NOPREFIX | WS_GROUP,11,61,59,8 - CONTROL "Mode:",2001,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | - WS_GROUP,11,50,59,8 - CONTROL "Version:",2000,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | - WS_GROUP,11,39,59,8 - GROUPBOX "Format Info",IDC_STATIC,5,29,70,56 - GROUPBOX "Audio Info",IDC_STATIC,79,29,78,56 - CONTROL "Bits Per Sample:",3002,"Static",SS_LEFTNOWORDWRAP | - SS_NOPREFIX | WS_GROUP,86,61,66,8 - CONTROL "Channels:",3001,"Static",SS_LEFTNOWORDWRAP | - SS_NOPREFIX | WS_GROUP,86,50,66,8 - CONTROL "Sample Rate:",3000,"Static",SS_LEFTNOWORDWRAP | - SS_NOPREFIX | WS_GROUP,86,39,66,8 - GROUPBOX "Tag Info",IDC_STATIC,5,88,240,94 - LTEXT "Album:",IDC_STATIC,11,134,23,8,SS_NOPREFIX - LTEXT "Artist:",IDC_STATIC,11,118,23,8,SS_NOPREFIX - LTEXT "Title:",IDC_STATIC,11,102,18,8,SS_NOPREFIX - LTEXT "Comment:",IDC_STATIC,11,150,33,8,SS_NOPREFIX - LTEXT "Year:",IDC_STATIC,11,166,18,8,SS_NOPREFIX - LTEXT "Genre: ",IDC_STATIC,82,166,24,8,SS_NOPREFIX - CONTROL "Length:",4000,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | - WS_GROUP,167,39,71,8 - CONTROL "Compression:",4003,"Static",SS_LEFTNOWORDWRAP | - SS_NOPREFIX | WS_GROUP,167,72,71,8 - LTEXT "Track:",IDC_STATIC,195,166,22,8,SS_NOPREFIX - GROUPBOX "Exit",IDC_STATIC,5,185,240,29 - CONTROL "Peak Level:",3003,"Static",SS_LEFTNOWORDWRAP | - SS_NOPREFIX | WS_GROUP,86,72,66,8 - EDITTEXT 1000,28,4,193,18,ES_CENTER | ES_MULTILINE | - ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - CONTROL "APE:",4002,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | - WS_GROUP,167,61,71,8 - CONTROL "Tagged:",2003,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | - WS_GROUP,11,71,59,9 - GROUPBOX "Length / Size Info",IDC_STATIC,161,29,83,56 - CONTROL "WAV:",4001,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | - WS_GROUP,167,50,71,8 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,9,0 - PRODUCTVERSION 3,9,9,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "Compression and decompression library for Monkey's Audio" - VALUE "CompanyName", "Matthew T. Ashland" - VALUE "FileDescription", "Monkey's Audio DLL Library" - VALUE "FileVersion", "3.99" - VALUE "LegalCopyright", "Copyright © 2000-2004" - VALUE "OriginalFilename", "MACDll.dll" - VALUE "ProductName", "Monkey's Audio" - VALUE "ProductVersion", "3.99" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/MAC_SDK/Source/MACDll/resource.h b/MAC_SDK/Source/MACDll/resource.h deleted file mode 100644 index 6e97749..0000000 --- a/MAC_SDK/Source/MACDll/resource.h +++ /dev/null @@ -1,20 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Resource Script.rc -// -#define IDD_DIALOG1 101 -#define IDD_WAV_INFO 101 -#define IDD_APE_INFO 103 -#define IDI_MONKEY_LEFT 105 -#define IDI_MONKEY_RIGHT 106 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 149 -#define _APS_NEXT_COMMAND_VALUE 40002 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/MAC_SDK/Source/MACLib/APECompress.cpp b/MAC_SDK/Source/MACLib/APECompress.cpp deleted file mode 100644 index 8cd14e4..0000000 --- a/MAC_SDK/Source/MACLib/APECompress.cpp +++ /dev/null @@ -1,250 +0,0 @@ -#include "All.h" -#include "APECompress.h" -#ifdef IO_CLASS_NAME -#include IO_HEADER_FILE -#endif -#include "APECompressCreate.h" -#include "WAVInputSource.h" - -CAPECompress::CAPECompress() -{ - m_nBufferHead = 0; - m_nBufferTail = 0; - m_nBufferSize = 0; - m_bBufferLocked = FALSE; - m_bOwnsOutputIO = FALSE; - m_pioOutput = NULL; - - m_spAPECompressCreate.Assign(new CAPECompressCreate()); - - m_pBuffer = NULL; -} - -CAPECompress::~CAPECompress() -{ - SAFE_ARRAY_DELETE(m_pBuffer) - - if (m_bOwnsOutputIO) - { - SAFE_DELETE(m_pioOutput) - } -} - -#ifdef IO_CLASS_NAME -int CAPECompress::Start(const wchar_t * pOutputFilename, const WAVEFORMATEX * pwfeInput, int nMaxAudioBytes, int nCompressionLevel, const void * pHeaderData, int nHeaderBytes) -{ - m_pioOutput = new IO_CLASS_NAME; - m_bOwnsOutputIO = TRUE; - - if (m_pioOutput->Create(pOutputFilename) != 0) - { - return ERROR_INVALID_OUTPUT_FILE; - } - - m_spAPECompressCreate->Start(m_pioOutput, pwfeInput, nMaxAudioBytes, nCompressionLevel, - pHeaderData, nHeaderBytes); - - SAFE_ARRAY_DELETE(m_pBuffer) - m_nBufferSize = m_spAPECompressCreate->GetFullFrameBytes(); - m_pBuffer = new unsigned char [m_nBufferSize]; - memcpy(&m_wfeInput, pwfeInput, sizeof(WAVEFORMATEX)); - - return ERROR_SUCCESS; -} -#endif - -int CAPECompress::StartEx(CIO * pioOutput, const WAVEFORMATEX * pwfeInput, int nMaxAudioBytes, int nCompressionLevel, const void * pHeaderData, int nHeaderBytes) -{ - m_pioOutput = pioOutput; - m_bOwnsOutputIO = FALSE; - - m_spAPECompressCreate->Start(m_pioOutput, pwfeInput, nMaxAudioBytes, nCompressionLevel, - pHeaderData, nHeaderBytes); - - SAFE_ARRAY_DELETE(m_pBuffer) - m_nBufferSize = m_spAPECompressCreate->GetFullFrameBytes(); - m_pBuffer = new unsigned char [m_nBufferSize]; - memcpy(&m_wfeInput, pwfeInput, sizeof(WAVEFORMATEX)); - - return ERROR_SUCCESS; -} - -int CAPECompress::GetBufferBytesAvailable() -{ - return m_nBufferSize - m_nBufferTail; -} - -int CAPECompress::UnlockBuffer(int nBytesAdded, BOOL bProcess) -{ - if (m_bBufferLocked == FALSE) - return ERROR_UNDEFINED; - - m_nBufferTail += nBytesAdded; - m_bBufferLocked = FALSE; - - if (bProcess) - { - int nRetVal = ProcessBuffer(); - if (nRetVal != 0) { return nRetVal; } - } - - return ERROR_SUCCESS; -} - -unsigned char * CAPECompress::LockBuffer(int * pBytesAvailable) -{ - if (m_pBuffer == NULL) { return NULL; } - - if (m_bBufferLocked) - return NULL; - - m_bBufferLocked = TRUE; - - if (pBytesAvailable) - *pBytesAvailable = GetBufferBytesAvailable(); - - return &m_pBuffer[m_nBufferTail]; -} - -int CAPECompress::AddData(unsigned char * pData, int nBytes) -{ - if (m_pBuffer == NULL) return ERROR_INSUFFICIENT_MEMORY; - - int nBytesDone = 0; - - while (nBytesDone < nBytes) - { - // lock the buffer - int nBytesAvailable = 0; - unsigned char * pBuffer = LockBuffer(&nBytesAvailable); - if (pBuffer == NULL || nBytesAvailable <= 0) - return ERROR_UNDEFINED; - - // calculate how many bytes to copy and add that much to the buffer - int nBytesToProcess = min(nBytesAvailable, nBytes - nBytesDone); - memcpy(pBuffer, &pData[nBytesDone], nBytesToProcess); - - // unlock the buffer (fail if not successful) - int nRetVal = UnlockBuffer(nBytesToProcess); - if (nRetVal != ERROR_SUCCESS) - return nRetVal; - - // update our progress - nBytesDone += nBytesToProcess; - } - - return ERROR_SUCCESS; -} - -int CAPECompress::Finish(unsigned char * pTerminatingData, int nTerminatingBytes, int nWAVTerminatingBytes) -{ - RETURN_ON_ERROR(ProcessBuffer(TRUE)) - return m_spAPECompressCreate->Finish(pTerminatingData, nTerminatingBytes, nWAVTerminatingBytes); -} - -int CAPECompress::Kill() -{ - return ERROR_SUCCESS; -} - -int CAPECompress::ProcessBuffer(BOOL bFinalize) -{ - if (m_pBuffer == NULL) { return ERROR_UNDEFINED; } - - try - { - // process as much as possible - int nThreshold = (bFinalize) ? 0 : m_spAPECompressCreate->GetFullFrameBytes(); - - while ((m_nBufferTail - m_nBufferHead) >= nThreshold) - { - int nFrameBytes = min(m_spAPECompressCreate->GetFullFrameBytes(), m_nBufferTail - m_nBufferHead); - - if (nFrameBytes == 0) - break; - - int nRetVal = m_spAPECompressCreate->EncodeFrame(&m_pBuffer[m_nBufferHead], nFrameBytes); - if (nRetVal != 0) { return nRetVal; } - - m_nBufferHead += nFrameBytes; - } - - // shift the buffer - if (m_nBufferHead != 0) - { - int nBytesLeft = m_nBufferTail - m_nBufferHead; - - if (nBytesLeft != 0) - memmove(m_pBuffer, &m_pBuffer[m_nBufferHead], nBytesLeft); - - m_nBufferTail -= m_nBufferHead; - m_nBufferHead = 0; - } - } - catch(...) - { - return ERROR_UNDEFINED; - } - - return ERROR_SUCCESS; -} - -int CAPECompress::AddDataFromInputSource(CInputSource * pInputSource, int nMaxBytes, int * pBytesAdded) -{ - // error check the parameters - if (pInputSource == NULL) return ERROR_BAD_PARAMETER; - - // initialize - if (pBytesAdded) *pBytesAdded = 0; - - // lock the buffer - int nBytesAvailable = 0; - unsigned char * pBuffer = LockBuffer(&nBytesAvailable); - if ((pBuffer == NULL) || (nBytesAvailable == 0)) - return ERROR_INSUFFICIENT_MEMORY; - - // calculate the 'ideal' number of bytes - unsigned int nBytesRead = 0; - - int nIdealBytes = m_spAPECompressCreate->GetFullFrameBytes() - (m_nBufferTail - m_nBufferHead); - if (nIdealBytes > 0) - { - // get the data - int nBytesToAdd = nBytesAvailable; - - if (nMaxBytes > 0) - { - if (nBytesToAdd > nMaxBytes) nBytesToAdd = nMaxBytes; - } - - if (nBytesToAdd > nIdealBytes) nBytesToAdd = nIdealBytes; - - // always make requests along block boundaries - while ((nBytesToAdd % m_wfeInput.nBlockAlign) != 0) - nBytesToAdd--; - - int nBlocksToAdd = nBytesToAdd / m_wfeInput.nBlockAlign; - - // get data - int nBlocksAdded = 0; - int nRetVal = pInputSource->GetData(pBuffer, nBlocksToAdd, &nBlocksAdded); - if (nRetVal != 0) - return ERROR_IO_READ; - else - nBytesRead = (nBlocksAdded * m_wfeInput.nBlockAlign); - - // store the bytes read - if (pBytesAdded) - *pBytesAdded = nBytesRead; - } - - // unlock the data and process - int nRetVal = UnlockBuffer(nBytesRead, TRUE); - if (nRetVal != 0) - { - return nRetVal; - } - - return ERROR_SUCCESS; -} - diff --git a/MAC_SDK/Source/MACLib/APECompress.h b/MAC_SDK/Source/MACLib/APECompress.h deleted file mode 100644 index e91bd56..0000000 --- a/MAC_SDK/Source/MACLib/APECompress.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef APE_APECOMPRESS_H -#define APE_APECOMPRESS_H - -#include "MACLib.h" -class CAPECompressCreate; - -/************************************************************************************************* -CAPECompress - uses the CAPECompressHub to provide a simpler compression interface (with buffering, etc) -*************************************************************************************************/ -class CAPECompress : public IAPECompress -{ -public: - - CAPECompress(); - ~CAPECompress(); - - // start encoding -#ifdef IO_CLASS_NAME - int Start(const wchar_t * pOutputFilename, const WAVEFORMATEX * pwfeInput, int nMaxAudioBytes, int nCompressionLevel = COMPRESSION_LEVEL_NORMAL, const void * pHeaderData = NULL, int nHeaderBytes = CREATE_WAV_HEADER_ON_DECOMPRESSION); -#endif - int StartEx(CIO * pioOutput, const WAVEFORMATEX * pwfeInput, int nMaxAudioBytes, int nCompressionLevel = COMPRESSION_LEVEL_NORMAL, const void * pHeaderData = NULL, int nHeaderBytes = CREATE_WAV_HEADER_ON_DECOMPRESSION); - - // add data / compress data - - // allows linear, immediate access to the buffer (fast) - int GetBufferBytesAvailable(); - int UnlockBuffer(int nBytesAdded, BOOL bProcess = TRUE); - unsigned char * LockBuffer(int * pBytesAvailable); - - // slower, but easier than locking and unlocking (copies data) - int AddData(unsigned char * pData, int nBytes); - - // use a CIO (input source) to add data - int AddDataFromInputSource(CInputSource * pInputSource, int nMaxBytes = -1, int * pBytesAdded = NULL); - - // finish / kill - int Finish(unsigned char * pTerminatingData, int nTerminatingBytes, int nWAVTerminatingBytes); - int Kill(); - -private: - - int ProcessBuffer(BOOL bFinalize = FALSE); - - CSmartPtr m_spAPECompressCreate; - - int m_nBufferHead; - int m_nBufferTail; - int m_nBufferSize; - unsigned char * m_pBuffer; - BOOL m_bBufferLocked; - - CIO * m_pioOutput; - BOOL m_bOwnsOutputIO; - WAVEFORMATEX m_wfeInput; - -}; - -#endif // #ifndef APE_APECOMPRESS_H diff --git a/MAC_SDK/Source/MACLib/APECompressCore.cpp b/MAC_SDK/Source/MACLib/APECompressCore.cpp deleted file mode 100644 index 657e8c7..0000000 --- a/MAC_SDK/Source/MACLib/APECompressCore.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "All.h" -#include "APECompressCore.h" - -#include "BitArray.h" -#include "Prepare.h" -#include "NewPredictor.h" - -CAPECompressCore::CAPECompressCore(CIO * pIO, const WAVEFORMATEX * pwfeInput, int nMaxFrameBlocks, int nCompressionLevel) -{ - m_spBitArray.Assign(new CBitArray(pIO)); - m_spDataX.Assign(new int [nMaxFrameBlocks], TRUE); - m_spDataY.Assign(new int [nMaxFrameBlocks], TRUE); - m_spTempData.Assign(new int [nMaxFrameBlocks], TRUE); - m_spPrepare.Assign(new CPrepare); - m_spPredictorX.Assign(new CPredictorCompressNormal(nCompressionLevel)); - m_spPredictorY.Assign(new CPredictorCompressNormal(nCompressionLevel)); - - memcpy(&m_wfeInput, pwfeInput, sizeof(WAVEFORMATEX)); - m_nPeakLevel = 0; -} - -CAPECompressCore::~CAPECompressCore() -{ -} - -int CAPECompressCore::EncodeFrame(const void * pInputData, int nInputBytes) -{ - // variables - const int nInputBlocks = nInputBytes / m_wfeInput.nBlockAlign; - int nSpecialCodes = 0; - - // always start a new frame on a byte boundary - m_spBitArray->AdvanceToByteBoundary(); - - // do the preparation stage - RETURN_ON_ERROR(Prepare(pInputData, nInputBytes, &nSpecialCodes)) - - m_spPredictorX->Flush(); - m_spPredictorY->Flush(); - - m_spBitArray->FlushState(m_BitArrayStateX); - m_spBitArray->FlushState(m_BitArrayStateY); - - m_spBitArray->FlushBitArray(); - - if (m_wfeInput.nChannels == 2) - { - BOOL bEncodeX = TRUE; - BOOL bEncodeY = TRUE; - - if ((nSpecialCodes & SPECIAL_FRAME_LEFT_SILENCE) && - (nSpecialCodes & SPECIAL_FRAME_RIGHT_SILENCE)) - { - bEncodeX = FALSE; - bEncodeY = FALSE; - } - - if (nSpecialCodes & SPECIAL_FRAME_PSEUDO_STEREO) - { - bEncodeY = FALSE; - } - - if (bEncodeX && bEncodeY) - { - int nLastX = 0; - for (int z = 0; z < nInputBlocks; z++) - { - m_spBitArray->EncodeValue(m_spPredictorY->CompressValue(m_spDataY[z], nLastX), m_BitArrayStateY); - m_spBitArray->EncodeValue(m_spPredictorX->CompressValue(m_spDataX[z], m_spDataY[z]), m_BitArrayStateX); - - nLastX = m_spDataX[z]; - } - } - else if (bEncodeX) - { - for (int z = 0; z < nInputBlocks; z++) - { - RETURN_ON_ERROR(m_spBitArray->EncodeValue(m_spPredictorX->CompressValue(m_spDataX[z]), m_BitArrayStateX)) - } - } - else if (bEncodeY) - { - for (int z = 0; z < nInputBlocks; z++) - { - RETURN_ON_ERROR(m_spBitArray->EncodeValue(m_spPredictorY->CompressValue(m_spDataY[z]), m_BitArrayStateY)) - } - } - } - else if (m_wfeInput.nChannels == 1) - { - if (!(nSpecialCodes & SPECIAL_FRAME_MONO_SILENCE)) - { - for (int z = 0; z < nInputBlocks; z++) - { - RETURN_ON_ERROR(m_spBitArray->EncodeValue(m_spPredictorX->CompressValue(m_spDataX[z]), m_BitArrayStateX)) - } - } - } - - m_spBitArray->Finalize(); - - // return success - return 0; -} - -int CAPECompressCore::Prepare(const void * pInputData, int nInputBytes, int * pSpecialCodes) -{ - // variable declares - *pSpecialCodes = 0; - unsigned int nCRC = 0; - - // do the preparation - RETURN_ON_ERROR(m_spPrepare->Prepare((unsigned char *) pInputData, nInputBytes, &m_wfeInput, m_spDataX, m_spDataY, - &nCRC, pSpecialCodes, &m_nPeakLevel)) - - // store the CRC - RETURN_ON_ERROR(m_spBitArray->EncodeUnsignedLong(nCRC)) - - // store any special codes - if (*pSpecialCodes != 0) - { - RETURN_ON_ERROR(m_spBitArray->EncodeUnsignedLong(*pSpecialCodes)) - } - - return 0; -} \ No newline at end of file diff --git a/MAC_SDK/Source/MACLib/APECompressCore.h b/MAC_SDK/Source/MACLib/APECompressCore.h deleted file mode 100644 index 5c3e8be..0000000 --- a/MAC_SDK/Source/MACLib/APECompressCore.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef APE_APECOMPRESSCORE_H -#define APE_APECOMPRESSCORE_H - -#include "APECompress.h" -#include "BitArray.h" - -class CPrepare; -class IPredictorCompress; - -/************************************************************************************************* -CAPECompressCore - manages the core of compression and bitstream output -*************************************************************************************************/ -class CAPECompressCore -{ -public: - CAPECompressCore(CIO * pIO, const WAVEFORMATEX * pwfeInput, int nMaxFrameBlocks, int nCompressionLevel); - ~CAPECompressCore(); - - int EncodeFrame(const void * pInputData, int nInputBytes); - - CBitArray * GetBitArray() { return m_spBitArray.GetPtr(); } - int GetPeakLevel() { return m_nPeakLevel; } - -private: - - int Prepare(const void * pInputData, int nInputBytes, int * pSpecialCodes); - - CSmartPtr m_spBitArray; - CSmartPtr m_spPredictorX; - CSmartPtr m_spPredictorY; - BIT_ARRAY_STATE m_BitArrayStateX; - BIT_ARRAY_STATE m_BitArrayStateY; - CSmartPtr m_spDataX; - CSmartPtr m_spDataY; - CSmartPtr m_spTempData; - CSmartPtr m_spPrepare; - WAVEFORMATEX m_wfeInput; - int m_nPeakLevel; -}; - -#endif // #ifndef APE_APECOMPRESSCORE_H diff --git a/MAC_SDK/Source/MACLib/APECompressCreate.cpp b/MAC_SDK/Source/MACLib/APECompressCreate.cpp deleted file mode 100644 index 5b6a088..0000000 --- a/MAC_SDK/Source/MACLib/APECompressCreate.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#include "All.h" -#include "IO.h" -#include "APECompressCreate.h" - -#include "APECompressCore.h" - -CAPECompressCreate::CAPECompressCreate() -{ - m_nMaxFrames = 0; -} - -CAPECompressCreate::~CAPECompressCreate() -{ -} - -int CAPECompressCreate::Start(CIO * pioOutput, const WAVEFORMATEX * pwfeInput, int nMaxAudioBytes, int nCompressionLevel, const void * pHeaderData, int nHeaderBytes) -{ - // verify the parameters - if (pioOutput == NULL || pwfeInput == NULL) - return ERROR_BAD_PARAMETER; - - // verify the wave format - if ((pwfeInput->nChannels != 1) && (pwfeInput->nChannels != 2)) - { - return ERROR_INPUT_FILE_UNSUPPORTED_CHANNEL_COUNT; - } - if ((pwfeInput->wBitsPerSample != 8) && (pwfeInput->wBitsPerSample != 16) && (pwfeInput->wBitsPerSample != 24)) - { - return ERROR_INPUT_FILE_UNSUPPORTED_BIT_DEPTH; - } - - // initialize (creates the base classes) - m_nSamplesPerFrame = 73728; - if (nCompressionLevel == COMPRESSION_LEVEL_EXTRA_HIGH) - m_nSamplesPerFrame *= 4; - else if (nCompressionLevel == COMPRESSION_LEVEL_INSANE) - m_nSamplesPerFrame *= 16; - - m_spIO.Assign(pioOutput, FALSE, FALSE); - m_spAPECompressCore.Assign(new CAPECompressCore(m_spIO, pwfeInput, m_nSamplesPerFrame, nCompressionLevel)); - - // copy the format - memcpy(&m_wfeInput, pwfeInput, sizeof(WAVEFORMATEX)); - - // the compression level - m_nCompressionLevel = nCompressionLevel; - m_nFrameIndex = 0; - m_nLastFrameBlocks = m_nSamplesPerFrame; - - // initialize the file - if (nMaxAudioBytes < 0) - nMaxAudioBytes = 2147483647; - - uint32 nMaxAudioBlocks = nMaxAudioBytes / pwfeInput->nBlockAlign; - int nMaxFrames = nMaxAudioBlocks / m_nSamplesPerFrame; - if ((nMaxAudioBlocks % m_nSamplesPerFrame) != 0) nMaxFrames++; - - InitializeFile(m_spIO, &m_wfeInput, nMaxFrames, - m_nCompressionLevel, pHeaderData, nHeaderBytes); - - return ERROR_SUCCESS; -} - -int CAPECompressCreate::GetFullFrameBytes() -{ - return m_nSamplesPerFrame * m_wfeInput.nBlockAlign; -} - -int CAPECompressCreate::EncodeFrame(const void * pInputData, int nInputBytes) -{ - int nInputBlocks = nInputBytes / m_wfeInput.nBlockAlign; - - if ((nInputBlocks < m_nSamplesPerFrame) && (m_nLastFrameBlocks < m_nSamplesPerFrame)) - { - return -1; // can only pass a smaller frame for the very last time - } - - // update the seek table - m_spAPECompressCore->GetBitArray()->AdvanceToByteBoundary(); - int nRetVal = SetSeekByte(m_nFrameIndex, m_spIO->GetPosition() + (m_spAPECompressCore->GetBitArray()->GetCurrentBitIndex() / 8)); - if (nRetVal != ERROR_SUCCESS) - return nRetVal; - - // compress - nRetVal = m_spAPECompressCore->EncodeFrame(pInputData, nInputBytes); - - // update stats - m_nLastFrameBlocks = nInputBlocks; - m_nFrameIndex++; - - return nRetVal; -} - -int CAPECompressCreate::Finish(const void * pTerminatingData, int nTerminatingBytes, int nWAVTerminatingBytes) -{ - // clear the bit array - RETURN_ON_ERROR(m_spAPECompressCore->GetBitArray()->OutputBitArray(TRUE)); - - // finalize the file - RETURN_ON_ERROR(FinalizeFile(m_spIO, m_nFrameIndex, m_nLastFrameBlocks, - pTerminatingData, nTerminatingBytes, nWAVTerminatingBytes, m_spAPECompressCore->GetPeakLevel())); - - return ERROR_SUCCESS; -} - -int CAPECompressCreate::SetSeekByte(int nFrame, int nByteOffset) -{ - if (nFrame >= m_nMaxFrames) return ERROR_APE_COMPRESS_TOO_MUCH_DATA; - m_spSeekTable[nFrame] = nByteOffset; - return ERROR_SUCCESS; -} - -int CAPECompressCreate::InitializeFile(CIO * pIO, const WAVEFORMATEX * pwfeInput, int nMaxFrames, int nCompressionLevel, const void * pHeaderData, int nHeaderBytes) -{ - // error check the parameters - if (pIO == NULL || pwfeInput == NULL || nMaxFrames <= 0) - return ERROR_BAD_PARAMETER; - - APE_DESCRIPTOR APEDescriptor; memset(&APEDescriptor, 0, sizeof(APEDescriptor)); - APE_HEADER APEHeader; memset(&APEHeader, 0, sizeof(APEHeader)); - - // create the descriptor (only fill what we know) - APEDescriptor.cID[0] = 'M'; - APEDescriptor.cID[1] = 'A'; - APEDescriptor.cID[2] = 'C'; - APEDescriptor.cID[3] = ' '; - APEDescriptor.nVersion = MAC_VERSION_NUMBER; - - APEDescriptor.nDescriptorBytes = sizeof(APEDescriptor); - APEDescriptor.nHeaderBytes = sizeof(APEHeader); - APEDescriptor.nSeekTableBytes = nMaxFrames * sizeof(unsigned int); - APEDescriptor.nHeaderDataBytes = (nHeaderBytes == CREATE_WAV_HEADER_ON_DECOMPRESSION) ? 0 : nHeaderBytes; - - // create the header (only fill what we know now) - APEHeader.nBitsPerSample = pwfeInput->wBitsPerSample; - APEHeader.nChannels = pwfeInput->nChannels; - APEHeader.nSampleRate = pwfeInput->nSamplesPerSec; - - APEHeader.nCompressionLevel = (uint16) nCompressionLevel; - APEHeader.nFormatFlags = (nHeaderBytes == CREATE_WAV_HEADER_ON_DECOMPRESSION) ? MAC_FORMAT_FLAG_CREATE_WAV_HEADER : 0; - - APEHeader.nBlocksPerFrame = m_nSamplesPerFrame; - - // write the data to the file - unsigned int nBytesWritten = 0; - RETURN_ON_ERROR(pIO->Write(&APEDescriptor, sizeof(APEDescriptor), &nBytesWritten)) - RETURN_ON_ERROR(pIO->Write(&APEHeader, sizeof(APEHeader), &nBytesWritten)) - - // write an empty seek table - m_spSeekTable.Assign(new uint32 [nMaxFrames], TRUE); - if (m_spSeekTable == NULL) { return ERROR_INSUFFICIENT_MEMORY; } - ZeroMemory(m_spSeekTable, nMaxFrames * 4); - RETURN_ON_ERROR(pIO->Write(m_spSeekTable, (nMaxFrames * 4), &nBytesWritten)) - m_nMaxFrames = nMaxFrames; - - // write the WAV data - if ((pHeaderData != NULL) && (nHeaderBytes > 0) && (nHeaderBytes != CREATE_WAV_HEADER_ON_DECOMPRESSION)) - { - m_spAPECompressCore->GetBitArray()->GetMD5Helper().AddData(pHeaderData, nHeaderBytes); - RETURN_ON_ERROR(pIO->Write((void *) pHeaderData, nHeaderBytes, &nBytesWritten)) - } - - return ERROR_SUCCESS; -} - - -int CAPECompressCreate::FinalizeFile(CIO * pIO, int nNumberOfFrames, int nFinalFrameBlocks, const void * pTerminatingData, int nTerminatingBytes, int nWAVTerminatingBytes, int nPeakLevel) -{ - // store the tail position - int nTailPosition = pIO->GetPosition(); - - // append the terminating data - unsigned int nBytesWritten = 0; - unsigned int nBytesRead = 0; - int nRetVal = 0; - if (nTerminatingBytes > 0) - { - m_spAPECompressCore->GetBitArray()->GetMD5Helper().AddData(pTerminatingData, nTerminatingBytes); - if (pIO->Write((void *) pTerminatingData, nTerminatingBytes, &nBytesWritten) != 0) { return ERROR_IO_WRITE; } - } - - // go to the beginning and update the information - nRetVal = pIO->Seek(0, FILE_BEGIN); - - // get the descriptor - APE_DESCRIPTOR APEDescriptor; - nRetVal = pIO->Read(&APEDescriptor, sizeof(APEDescriptor), &nBytesRead); - if ((nRetVal != 0) || (nBytesRead != sizeof(APEDescriptor))) { return ERROR_IO_READ; } - - // get the header - APE_HEADER APEHeader; - nRetVal = pIO->Read(&APEHeader, sizeof(APEHeader), &nBytesRead); - if (nRetVal != 0 || nBytesRead != sizeof(APEHeader)) { return ERROR_IO_READ; } - - // update the header - APEHeader.nFinalFrameBlocks = nFinalFrameBlocks; - APEHeader.nTotalFrames = nNumberOfFrames; - - // update the descriptor - APEDescriptor.nAPEFrameDataBytes = nTailPosition - (APEDescriptor.nDescriptorBytes + APEDescriptor.nHeaderBytes + APEDescriptor.nSeekTableBytes + APEDescriptor.nHeaderDataBytes); - APEDescriptor.nAPEFrameDataBytesHigh = 0; - APEDescriptor.nTerminatingDataBytes = nTerminatingBytes; - - // update the MD5 - m_spAPECompressCore->GetBitArray()->GetMD5Helper().AddData(&APEHeader, sizeof(APEHeader)); - m_spAPECompressCore->GetBitArray()->GetMD5Helper().AddData(m_spSeekTable, m_nMaxFrames * 4); - m_spAPECompressCore->GetBitArray()->GetMD5Helper().GetResult(APEDescriptor.cFileMD5); - - // set the pointer and re-write the updated header and peak level - nRetVal = pIO->Seek(0, FILE_BEGIN); - if (pIO->Write(&APEDescriptor, sizeof(APEDescriptor), &nBytesWritten) != 0) { return ERROR_IO_WRITE; } - if (pIO->Write(&APEHeader, sizeof(APEHeader), &nBytesWritten) != 0) { return ERROR_IO_WRITE; } - - // write the updated seek table - if (pIO->Write(m_spSeekTable, m_nMaxFrames * 4, &nBytesWritten) != 0) { return ERROR_IO_WRITE; } - - return ERROR_SUCCESS; -} diff --git a/MAC_SDK/Source/MACLib/APECompressCreate.h b/MAC_SDK/Source/MACLib/APECompressCreate.h deleted file mode 100644 index f751039..0000000 --- a/MAC_SDK/Source/MACLib/APECompressCreate.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef APE_APECOMPRESSCREATE_H -#define APE_APECOMPRESSCREATE_H - -#include "APECompress.h" - -class CAPECompressCore; - -class CAPECompressCreate -{ -public: - CAPECompressCreate(); - ~CAPECompressCreate(); - - int InitializeFile(CIO * pIO, const WAVEFORMATEX * pwfeInput, int nMaxFrames, int nCompressionLevel, const void * pHeaderData, int nHeaderBytes); - int FinalizeFile(CIO * pIO, int nNumberOfFrames, int nFinalFrameBlocks, const void * pTerminatingData, int nTerminatingBytes, int nWAVTerminatingBytes, int nPeakLevel); - - int SetSeekByte(int nFrame, int nByteOffset); - - int Start(CIO * pioOutput, const WAVEFORMATEX * pwfeInput, int nMaxAudioBytes, int nCompressionLevel = COMPRESSION_LEVEL_NORMAL, const void * pHeaderData = NULL, int nHeaderBytes = CREATE_WAV_HEADER_ON_DECOMPRESSION); - - int GetFullFrameBytes(); - int EncodeFrame(const void * pInputData, int nInputBytes); - - int Finish(const void * pTerminatingData, int nTerminatingBytes, int nWAVTerminatingBytes); - - -private: - - CSmartPtr m_spSeekTable; - int m_nMaxFrames; - - CSmartPtr m_spIO; - CSmartPtr m_spAPECompressCore; - - WAVEFORMATEX m_wfeInput; - int m_nCompressionLevel; - int m_nSamplesPerFrame; - int m_nFrameIndex; - int m_nLastFrameBlocks; - -}; - -#endif // #ifndef APE_APECOMPRESSCREATE_H diff --git a/MAC_SDK/Source/MACLib/APEDecompress.cpp b/MAC_SDK/Source/MACLib/APEDecompress.cpp deleted file mode 100644 index 1db1585..0000000 --- a/MAC_SDK/Source/MACLib/APEDecompress.cpp +++ /dev/null @@ -1,479 +0,0 @@ -#include "All.h" -#include "APEDecompress.h" - -#include "APEInfo.h" -#include "Prepare.h" -#include "UnBitArray.h" -#include "NewPredictor.h" - -#define DECODE_BLOCK_SIZE 4096 - -CAPEDecompress::CAPEDecompress(int * pErrorCode, CAPEInfo * pAPEInfo, int nStartBlock, int nFinishBlock) -{ - *pErrorCode = ERROR_SUCCESS; - - // open / analyze the file - m_spAPEInfo.Assign(pAPEInfo); - - // version check (this implementation only works with 3.93 and later files) - if (GetInfo(APE_INFO_FILE_VERSION) < 3930) - { - *pErrorCode = ERROR_UNDEFINED; - return; - } - - // get format information - GetInfo(APE_INFO_WAVEFORMATEX, (int) &m_wfeInput); - m_nBlockAlign = GetInfo(APE_INFO_BLOCK_ALIGN); - - // initialize other stuff - m_bDecompressorInitialized = FALSE; - m_nCurrentFrame = 0; - m_nCurrentBlock = 0; - m_nCurrentFrameBufferBlock = 0; - m_nFrameBufferFinishedBlocks = 0; - m_bErrorDecodingCurrentFrame = FALSE; - - // set the "real" start and finish blocks - m_nStartBlock = (nStartBlock < 0) ? 0 : min(nStartBlock, GetInfo(APE_INFO_TOTAL_BLOCKS)); - m_nFinishBlock = (nFinishBlock < 0) ? GetInfo(APE_INFO_TOTAL_BLOCKS) : min(nFinishBlock, GetInfo(APE_INFO_TOTAL_BLOCKS)); - m_bIsRanged = (m_nStartBlock != 0) || (m_nFinishBlock != GetInfo(APE_INFO_TOTAL_BLOCKS)); -} - -CAPEDecompress::~CAPEDecompress() -{ - -} - -int CAPEDecompress::InitializeDecompressor() -{ - // check if we have anything to do - if (m_bDecompressorInitialized) - return ERROR_SUCCESS; - - // update the initialized flag - m_bDecompressorInitialized = TRUE; - - // create a frame buffer - m_cbFrameBuffer.CreateBuffer((GetInfo(APE_INFO_BLOCKS_PER_FRAME) + DECODE_BLOCK_SIZE) * m_nBlockAlign, m_nBlockAlign * 64); - - // create decoding components - m_spUnBitArray.Assign((CUnBitArrayBase *) CreateUnBitArray(this, GetInfo(APE_INFO_FILE_VERSION))); - - if (GetInfo(APE_INFO_FILE_VERSION) >= 3950) - { - m_spNewPredictorX.Assign(new CPredictorDecompress3950toCurrent(GetInfo(APE_INFO_COMPRESSION_LEVEL), GetInfo(APE_INFO_FILE_VERSION))); - m_spNewPredictorY.Assign(new CPredictorDecompress3950toCurrent(GetInfo(APE_INFO_COMPRESSION_LEVEL), GetInfo(APE_INFO_FILE_VERSION))); - } - else - { - m_spNewPredictorX.Assign(new CPredictorDecompressNormal3930to3950(GetInfo(APE_INFO_COMPRESSION_LEVEL), GetInfo(APE_INFO_FILE_VERSION))); - m_spNewPredictorY.Assign(new CPredictorDecompressNormal3930to3950(GetInfo(APE_INFO_COMPRESSION_LEVEL), GetInfo(APE_INFO_FILE_VERSION))); - } - - // seek to the beginning - return Seek(0); -} - -int CAPEDecompress::GetData(char * pBuffer, int nBlocks, int * pBlocksRetrieved) -{ - int nRetVal = ERROR_SUCCESS; - if (pBlocksRetrieved) *pBlocksRetrieved = 0; - - // make sure we're initialized - RETURN_ON_ERROR(InitializeDecompressor()) - - // cap - int nBlocksUntilFinish = m_nFinishBlock - m_nCurrentBlock; - const int nBlocksToRetrieve = min(nBlocks, nBlocksUntilFinish); - - // get the data - unsigned char * pOutputBuffer = (unsigned char *) pBuffer; - int nBlocksLeft = nBlocksToRetrieve; int nBlocksThisPass = 1; - while ((nBlocksLeft > 0) && (nBlocksThisPass > 0)) - { - // fill up the frame buffer - int nDecodeRetVal = FillFrameBuffer(); - if (nDecodeRetVal != ERROR_SUCCESS) - nRetVal = nDecodeRetVal; - - // analyze how much to remove from the buffer - const int nFrameBufferBlocks = m_nFrameBufferFinishedBlocks; - nBlocksThisPass = min(nBlocksLeft, nFrameBufferBlocks); - - // remove as much as possible - if (nBlocksThisPass > 0) - { - m_cbFrameBuffer.Get(pOutputBuffer, nBlocksThisPass * m_nBlockAlign); - pOutputBuffer += nBlocksThisPass * m_nBlockAlign; - nBlocksLeft -= nBlocksThisPass; - m_nFrameBufferFinishedBlocks -= nBlocksThisPass; - } - } - - // calculate the blocks retrieved - int nBlocksRetrieved = nBlocksToRetrieve - nBlocksLeft; - - // update position - m_nCurrentBlock += nBlocksRetrieved; - if (pBlocksRetrieved) *pBlocksRetrieved = nBlocksRetrieved; - - return nRetVal; -} - -int CAPEDecompress::Seek(int nBlockOffset) -{ - RETURN_ON_ERROR(InitializeDecompressor()) - - // use the offset - nBlockOffset += m_nStartBlock; - - // cap (to prevent seeking too far) - if (nBlockOffset >= m_nFinishBlock) - nBlockOffset = m_nFinishBlock - 1; - if (nBlockOffset < m_nStartBlock) - nBlockOffset = m_nStartBlock; - - // seek to the perfect location - int nBaseFrame = nBlockOffset / GetInfo(APE_INFO_BLOCKS_PER_FRAME); - int nBlocksToSkip = nBlockOffset % GetInfo(APE_INFO_BLOCKS_PER_FRAME); - int nBytesToSkip = nBlocksToSkip * m_nBlockAlign; - - m_nCurrentBlock = nBaseFrame * GetInfo(APE_INFO_BLOCKS_PER_FRAME); - m_nCurrentFrameBufferBlock = nBaseFrame * GetInfo(APE_INFO_BLOCKS_PER_FRAME); - m_nCurrentFrame = nBaseFrame; - m_nFrameBufferFinishedBlocks = 0; - m_cbFrameBuffer.Empty(); - RETURN_ON_ERROR(SeekToFrame(m_nCurrentFrame)); - - // skip necessary blocks - CSmartPtr spTempBuffer(new char [nBytesToSkip], TRUE); - if (spTempBuffer == NULL) return ERROR_INSUFFICIENT_MEMORY; - - int nBlocksRetrieved = 0; - GetData(spTempBuffer, nBlocksToSkip, &nBlocksRetrieved); - if (nBlocksRetrieved != nBlocksToSkip) - return ERROR_UNDEFINED; - - return ERROR_SUCCESS; -} - -/***************************************************************************************** -Decodes blocks of data -*****************************************************************************************/ -int CAPEDecompress::FillFrameBuffer() -{ - int nRetVal = ERROR_SUCCESS; - - // determine the maximum blocks we can decode - // note that we won't do end capping because we can't use data - // until EndFrame(...) successfully handles the frame - // that means we may decode a little extra in end capping cases - // but this allows robust error handling of bad frames - int nMaxBlocks = m_cbFrameBuffer.MaxAdd() / m_nBlockAlign; - - // loop and decode data - int nBlocksLeft = nMaxBlocks; - while (nBlocksLeft > 0) - { - int nFrameBlocks = GetInfo(APE_INFO_FRAME_BLOCKS, m_nCurrentFrame); - if (nFrameBlocks < 0) - break; - - int nFrameOffsetBlocks = m_nCurrentFrameBufferBlock % GetInfo(APE_INFO_BLOCKS_PER_FRAME); - int nFrameBlocksLeft = nFrameBlocks - nFrameOffsetBlocks; - int nBlocksThisPass = min(nFrameBlocksLeft, nBlocksLeft); - - // start the frame if we need to - if (nFrameOffsetBlocks == 0) - StartFrame(); - - // store the frame buffer bytes before we start - int nFrameBufferBytes = m_cbFrameBuffer.MaxGet(); - - // decode data - DecodeBlocksToFrameBuffer(nBlocksThisPass); - - // end the frame if we need to - if ((nFrameOffsetBlocks + nBlocksThisPass) >= nFrameBlocks) - { - EndFrame(); - if (m_bErrorDecodingCurrentFrame) - { - // remove any decoded data from the buffer - m_cbFrameBuffer.RemoveTail(m_cbFrameBuffer.MaxGet() - nFrameBufferBytes); - - // add silence - unsigned char cSilence = (GetInfo(APE_INFO_BITS_PER_SAMPLE) == 8) ? 127 : 0; - for (int z = 0; z < nFrameBlocks * m_nBlockAlign; z++) - { - *m_cbFrameBuffer.GetDirectWritePointer() = cSilence; - m_cbFrameBuffer.UpdateAfterDirectWrite(1); - } - - // seek to try to synchronize after an error - SeekToFrame(m_nCurrentFrame); - - // save the return value - nRetVal = ERROR_INVALID_CHECKSUM; - } - } - - nBlocksLeft -= nBlocksThisPass; - } - - return nRetVal; -} - -void CAPEDecompress::DecodeBlocksToFrameBuffer(int nBlocks) -{ - // decode the samples - int nBlocksProcessed = 0; - - try - { - if (m_wfeInput.nChannels == 2) - { - if ((m_nSpecialCodes & SPECIAL_FRAME_LEFT_SILENCE) && - (m_nSpecialCodes & SPECIAL_FRAME_RIGHT_SILENCE)) - { - for (nBlocksProcessed = 0; nBlocksProcessed < nBlocks; nBlocksProcessed++) - { - m_Prepare.Unprepare(0, 0, &m_wfeInput, m_cbFrameBuffer.GetDirectWritePointer(), &m_nCRC); - m_cbFrameBuffer.UpdateAfterDirectWrite(m_nBlockAlign); - } - } - else if (m_nSpecialCodes & SPECIAL_FRAME_PSEUDO_STEREO) - { - for (nBlocksProcessed = 0; nBlocksProcessed < nBlocks; nBlocksProcessed++) - { - int X = m_spNewPredictorX->DecompressValue(m_spUnBitArray->DecodeValueRange(m_BitArrayStateX)); - m_Prepare.Unprepare(X, 0, &m_wfeInput, m_cbFrameBuffer.GetDirectWritePointer(), &m_nCRC); - m_cbFrameBuffer.UpdateAfterDirectWrite(m_nBlockAlign); - } - } - else - { - if (m_spAPEInfo->GetInfo(APE_INFO_FILE_VERSION) >= 3950) - { - for (nBlocksProcessed = 0; nBlocksProcessed < nBlocks; nBlocksProcessed++) - { - int nY = m_spUnBitArray->DecodeValueRange(m_BitArrayStateY); - int nX = m_spUnBitArray->DecodeValueRange(m_BitArrayStateX); - int Y = m_spNewPredictorY->DecompressValue(nY, m_nLastX); - int X = m_spNewPredictorX->DecompressValue(nX, Y); - m_nLastX = X; - - m_Prepare.Unprepare(X, Y, &m_wfeInput, m_cbFrameBuffer.GetDirectWritePointer(), &m_nCRC); - m_cbFrameBuffer.UpdateAfterDirectWrite(m_nBlockAlign); - } - } - else - { - for (nBlocksProcessed = 0; nBlocksProcessed < nBlocks; nBlocksProcessed++) - { - int X = m_spNewPredictorX->DecompressValue(m_spUnBitArray->DecodeValueRange(m_BitArrayStateX)); - int Y = m_spNewPredictorY->DecompressValue(m_spUnBitArray->DecodeValueRange(m_BitArrayStateY)); - - m_Prepare.Unprepare(X, Y, &m_wfeInput, m_cbFrameBuffer.GetDirectWritePointer(), &m_nCRC); - m_cbFrameBuffer.UpdateAfterDirectWrite(m_nBlockAlign); - } - } - } - } - else - { - if (m_nSpecialCodes & SPECIAL_FRAME_MONO_SILENCE) - { - for (nBlocksProcessed = 0; nBlocksProcessed < nBlocks; nBlocksProcessed++) - { - m_Prepare.Unprepare(0, 0, &m_wfeInput, m_cbFrameBuffer.GetDirectWritePointer(), &m_nCRC); - m_cbFrameBuffer.UpdateAfterDirectWrite(m_nBlockAlign); - } - } - else - { - for (nBlocksProcessed = 0; nBlocksProcessed < nBlocks; nBlocksProcessed++) - { - int X = m_spNewPredictorX->DecompressValue(m_spUnBitArray->DecodeValueRange(m_BitArrayStateX)); - m_Prepare.Unprepare(X, 0, &m_wfeInput, m_cbFrameBuffer.GetDirectWritePointer(), &m_nCRC); - m_cbFrameBuffer.UpdateAfterDirectWrite(m_nBlockAlign); - } - } - } - } - catch(...) - { - m_bErrorDecodingCurrentFrame = TRUE; - } - - m_nCurrentFrameBufferBlock += nBlocks; -} - -void CAPEDecompress::StartFrame() -{ - m_nCRC = 0xFFFFFFFF; - - // get the frame header - m_nStoredCRC = m_spUnBitArray->DecodeValue(DECODE_VALUE_METHOD_UNSIGNED_INT); - m_bErrorDecodingCurrentFrame = FALSE; - - // get any 'special' codes if the file uses them (for silence, FALSE stereo, etc.) - m_nSpecialCodes = 0; - if (GET_USES_SPECIAL_FRAMES(m_spAPEInfo)) - { - if (m_nStoredCRC & 0x80000000) - { - m_nSpecialCodes = m_spUnBitArray->DecodeValue(DECODE_VALUE_METHOD_UNSIGNED_INT); - } - m_nStoredCRC &= 0x7FFFFFFF; - } - - m_spNewPredictorX->Flush(); - m_spNewPredictorY->Flush(); - - m_spUnBitArray->FlushState(m_BitArrayStateX); - m_spUnBitArray->FlushState(m_BitArrayStateY); - - m_spUnBitArray->FlushBitArray(); - - m_nLastX = 0; -} - -void CAPEDecompress::EndFrame() -{ - m_nFrameBufferFinishedBlocks += GetInfo(APE_INFO_FRAME_BLOCKS, m_nCurrentFrame); - m_nCurrentFrame++; - - // finalize - m_spUnBitArray->Finalize(); - - // check the CRC - m_nCRC = m_nCRC ^ 0xFFFFFFFF; - m_nCRC >>= 1; - if (m_nCRC != m_nStoredCRC) - m_bErrorDecodingCurrentFrame = TRUE; -} - -/***************************************************************************************** -Seek to the proper frame (if necessary) and do any alignment of the bit array -*****************************************************************************************/ -int CAPEDecompress::SeekToFrame(int nFrameIndex) -{ - int nSeekRemainder = (GetInfo(APE_INFO_SEEK_BYTE, nFrameIndex) - GetInfo(APE_INFO_SEEK_BYTE, 0)) % 4; - return m_spUnBitArray->FillAndResetBitArray(GetInfo(APE_INFO_SEEK_BYTE, nFrameIndex) - nSeekRemainder, nSeekRemainder * 8); -} - -/***************************************************************************************** -Get information from the decompressor -*****************************************************************************************/ -int CAPEDecompress::GetInfo(APE_DECOMPRESS_FIELDS Field, int nParam1, int nParam2) -{ - int nRetVal = 0; - BOOL bHandled = TRUE; - - switch (Field) - { - case APE_DECOMPRESS_CURRENT_BLOCK: - nRetVal = m_nCurrentBlock - m_nStartBlock; - break; - case APE_DECOMPRESS_CURRENT_MS: - { - int nSampleRate = m_spAPEInfo->GetInfo(APE_INFO_SAMPLE_RATE, 0, 0); - if (nSampleRate > 0) - nRetVal = int((double(m_nCurrentBlock) * double(1000)) / double(nSampleRate)); - break; - } - case APE_DECOMPRESS_TOTAL_BLOCKS: - nRetVal = m_nFinishBlock - m_nStartBlock; - break; - case APE_DECOMPRESS_LENGTH_MS: - { - int nSampleRate = m_spAPEInfo->GetInfo(APE_INFO_SAMPLE_RATE, 0, 0); - if (nSampleRate > 0) - nRetVal = int((double(m_nFinishBlock - m_nStartBlock) * double(1000)) / double(nSampleRate)); - break; - } - case APE_DECOMPRESS_CURRENT_BITRATE: - nRetVal = GetInfo(APE_INFO_FRAME_BITRATE, m_nCurrentFrame); - break; - case APE_DECOMPRESS_AVERAGE_BITRATE: - { - if (m_bIsRanged) - { - // figure the frame range - const int nBlocksPerFrame = GetInfo(APE_INFO_BLOCKS_PER_FRAME); - int nStartFrame = m_nStartBlock / nBlocksPerFrame; - int nFinishFrame = (m_nFinishBlock + nBlocksPerFrame - 1) / nBlocksPerFrame; - - // get the number of bytes in the first and last frame - int nTotalBytes = (GetInfo(APE_INFO_FRAME_BYTES, nStartFrame) * (m_nStartBlock % nBlocksPerFrame)) / nBlocksPerFrame; - if (nFinishFrame != nStartFrame) - nTotalBytes += (GetInfo(APE_INFO_FRAME_BYTES, nFinishFrame) * (m_nFinishBlock % nBlocksPerFrame)) / nBlocksPerFrame; - - // get the number of bytes in between - const int nTotalFrames = GetInfo(APE_INFO_TOTAL_FRAMES); - for (int nFrame = nStartFrame + 1; (nFrame < nFinishFrame) && (nFrame < nTotalFrames); nFrame++) - nTotalBytes += GetInfo(APE_INFO_FRAME_BYTES, nFrame); - - // figure the bitrate - int nTotalMS = int((double(m_nFinishBlock - m_nStartBlock) * double(1000)) / double(GetInfo(APE_INFO_SAMPLE_RATE))); - if (nTotalMS != 0) - nRetVal = (nTotalBytes * 8) / nTotalMS; - } - else - { - nRetVal = GetInfo(APE_INFO_AVERAGE_BITRATE); - } - - break; - } - default: - bHandled = FALSE; - } - - if (!bHandled && m_bIsRanged) - { - bHandled = TRUE; - - switch (Field) - { - case APE_INFO_WAV_HEADER_BYTES: - nRetVal = sizeof(WAVE_HEADER); - break; - case APE_INFO_WAV_HEADER_DATA: - { - char * pBuffer = (char *) nParam1; - int nMaxBytes = nParam2; - - if (sizeof(WAVE_HEADER) > nMaxBytes) - { - nRetVal = -1; - } - else - { - WAVEFORMATEX wfeFormat; GetInfo(APE_INFO_WAVEFORMATEX, (int) &wfeFormat, 0); - WAVE_HEADER WAVHeader; FillWaveHeader(&WAVHeader, - (m_nFinishBlock - m_nStartBlock) * GetInfo(APE_INFO_BLOCK_ALIGN), - &wfeFormat, 0); - memcpy(pBuffer, &WAVHeader, sizeof(WAVE_HEADER)); - nRetVal = 0; - } - break; - } - case APE_INFO_WAV_TERMINATING_BYTES: - nRetVal = 0; - break; - case APE_INFO_WAV_TERMINATING_DATA: - nRetVal = 0; - break; - default: - bHandled = FALSE; - } - } - - if (bHandled == FALSE) - nRetVal = m_spAPEInfo->GetInfo(Field, nParam1, nParam2); - - return nRetVal; -} diff --git a/MAC_SDK/Source/MACLib/APEDecompress.h b/MAC_SDK/Source/MACLib/APEDecompress.h deleted file mode 100644 index ec49c07..0000000 --- a/MAC_SDK/Source/MACLib/APEDecompress.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef APE_APEDECOMPRESS_H -#define APE_APEDECOMPRESS_H - -#include "APEDecompress.h" - -class CUnBitArray; -class CPrepare; -class CAPEInfo; -class IPredictorDecompress; -#include "UnBitArrayBase.h" -#include "MACLib.h" -#include "Prepare.h" -#include "CircleBuffer.h" - -class CAPEDecompress : public IAPEDecompress -{ -public: - - CAPEDecompress(int * pErrorCode, CAPEInfo * pAPEInfo, int nStartBlock = -1, int nFinishBlock = -1); - ~CAPEDecompress(); - - int GetData(char * pBuffer, int nBlocks, int * pBlocksRetrieved); - int Seek(int nBlockOffset); - - int GetInfo(APE_DECOMPRESS_FIELDS Field, int nParam1 = 0, int nParam2 = 0); - -protected: - - // file info - int m_nBlockAlign; - int m_nCurrentFrame; - - // start / finish information - int m_nStartBlock; - int m_nFinishBlock; - int m_nCurrentBlock; - BOOL m_bIsRanged; - BOOL m_bDecompressorInitialized; - - // decoding tools - CPrepare m_Prepare; - WAVEFORMATEX m_wfeInput; - unsigned int m_nCRC; - unsigned int m_nStoredCRC; - int m_nSpecialCodes; - - int SeekToFrame(int nFrameIndex); - void DecodeBlocksToFrameBuffer(int nBlocks); - int FillFrameBuffer(); - void StartFrame(); - void EndFrame(); - int InitializeDecompressor(); - - // more decoding components - CSmartPtr m_spAPEInfo; - CSmartPtr m_spUnBitArray; - UNBIT_ARRAY_STATE m_BitArrayStateX; - UNBIT_ARRAY_STATE m_BitArrayStateY; - - CSmartPtr m_spNewPredictorX; - CSmartPtr m_spNewPredictorY; - - int m_nLastX; - - // decoding buffer - BOOL m_bErrorDecodingCurrentFrame; - int m_nCurrentFrameBufferBlock; - int m_nFrameBufferFinishedBlocks; - CCircleBuffer m_cbFrameBuffer; -}; - -#endif // #ifndef APE_APEDECOMPRESS_H diff --git a/MAC_SDK/Source/MACLib/APEHeader.cpp b/MAC_SDK/Source/MACLib/APEHeader.cpp deleted file mode 100644 index 51079d4..0000000 --- a/MAC_SDK/Source/MACLib/APEHeader.cpp +++ /dev/null @@ -1,280 +0,0 @@ -#include "All.h" -#include "APEHeader.h" -#include "MACLib.h" -#include "APEInfo.h" - -// TODO: should push and pop the file position - -CAPEHeader::CAPEHeader(CIO * pIO) -{ - m_pIO = pIO; -} - -CAPEHeader::~CAPEHeader() -{ - -} - -int CAPEHeader::FindDescriptor(BOOL bSeek) -{ - // store the original location and seek to the beginning - int nOriginalFileLocation = m_pIO->GetPosition(); - m_pIO->Seek(0, FILE_BEGIN); - - // set the default junk bytes to 0 - int nJunkBytes = 0; - - // skip an ID3v2 tag (which we really don't support anyway...) - unsigned int nBytesRead = 0; - unsigned char cID3v2Header[10]; - m_pIO->Read((unsigned char *) cID3v2Header, 10, &nBytesRead); - if (cID3v2Header[0] == 'I' && cID3v2Header[1] == 'D' && cID3v2Header[2] == '3') - { - // why is it so hard to figure the lenght of an ID3v2 tag ?!? - unsigned int nLength = *((unsigned int *) &cID3v2Header[6]); - - unsigned int nSyncSafeLength = 0; - nSyncSafeLength = (cID3v2Header[6] & 127) << 21; - nSyncSafeLength += (cID3v2Header[7] & 127) << 14; - nSyncSafeLength += (cID3v2Header[8] & 127) << 7; - nSyncSafeLength += (cID3v2Header[9] & 127); - - BOOL bHasTagFooter = FALSE; - - if (cID3v2Header[5] & 16) - { - bHasTagFooter = TRUE; - nJunkBytes = nSyncSafeLength + 20; - } - else - { - nJunkBytes = nSyncSafeLength + 10; - } - - // error check - if (cID3v2Header[5] & 64) - { - // this ID3v2 length calculator algorithm can't cope with extended headers - // we should be ok though, because the scan for the MAC header below should - // really do the trick - } - - m_pIO->Seek(nJunkBytes, FILE_BEGIN); - - // scan for padding (slow and stupid, but who cares here...) - if (!bHasTagFooter) - { - char cTemp = 0; - m_pIO->Read((unsigned char *) &cTemp, 1, &nBytesRead); - while (cTemp == 0 && nBytesRead == 1) - { - nJunkBytes++; - m_pIO->Read((unsigned char *) &cTemp, 1, &nBytesRead); - } - } - } - m_pIO->Seek(nJunkBytes, FILE_BEGIN); - - // scan until we hit the APE_DESCRIPTOR, the end of the file, or 1 MB later - unsigned int nGoalID = (' ' << 24) | ('C' << 16) | ('A' << 8) | ('M'); - unsigned int nReadID = 0; - int nRetVal = m_pIO->Read(&nReadID, 4, &nBytesRead); - if (nRetVal != 0 || nBytesRead != 4) return ERROR_UNDEFINED; - - nBytesRead = 1; - int nScanBytes = 0; - while ((nGoalID != nReadID) && (nBytesRead == 1) && (nScanBytes < (1024 * 1024))) - { - unsigned char cTemp; - m_pIO->Read(&cTemp, 1, &nBytesRead); - nReadID = (((unsigned int) cTemp) << 24) | (nReadID >> 8); - nJunkBytes++; - nScanBytes++; - } - - if (nGoalID != nReadID) - nJunkBytes = -1; - - // seek to the proper place (depending on result and settings) - if (bSeek && (nJunkBytes != -1)) - { - // successfully found the start of the file (seek to it and return) - m_pIO->Seek(nJunkBytes, FILE_BEGIN); - } - else - { - // restore the original file pointer - m_pIO->Seek(nOriginalFileLocation, FILE_BEGIN); - } - - return nJunkBytes; -} - -int CAPEHeader::Analyze(APE_FILE_INFO * pInfo) -{ - // error check - if ((m_pIO == NULL) || (pInfo == NULL)) - return ERROR_INVALID_PARAMETER; - - // variables - unsigned int nBytesRead = 0; - - // find the descriptor - pInfo->nJunkHeaderBytes = FindDescriptor(TRUE); - if (pInfo->nJunkHeaderBytes < 0) - return ERROR_UNDEFINED; - - // read the first 8 bytes of the descriptor (ID and version) - APE_COMMON_HEADER CommonHeader; memset(&CommonHeader, 0, sizeof(APE_COMMON_HEADER)); - m_pIO->Read(&CommonHeader, sizeof(APE_COMMON_HEADER), &nBytesRead); - - // make sure we're at the ID - if (CommonHeader.cID[0] != 'M' || CommonHeader.cID[1] != 'A' || CommonHeader.cID[2] != 'C' || CommonHeader.cID[3] != ' ') - return ERROR_UNDEFINED; - - int nRetVal = ERROR_UNDEFINED; - - if (CommonHeader.nVersion >= 3980) - { - // current header format - nRetVal = AnalyzeCurrent(pInfo); - } - else - { - // legacy support - nRetVal = AnalyzeOld(pInfo); - } - - return nRetVal; -} - -int CAPEHeader::AnalyzeCurrent(APE_FILE_INFO * pInfo) -{ - // variable declares - unsigned int nBytesRead = 0; - pInfo->spAPEDescriptor.Assign(new APE_DESCRIPTOR); memset(pInfo->spAPEDescriptor, 0, sizeof(APE_DESCRIPTOR)); - APE_HEADER APEHeader; memset(&APEHeader, 0, sizeof(APEHeader)); - - // read the descriptor - m_pIO->Seek(pInfo->nJunkHeaderBytes, FILE_BEGIN); - m_pIO->Read(pInfo->spAPEDescriptor, sizeof(APE_DESCRIPTOR), &nBytesRead); - - if ((pInfo->spAPEDescriptor->nDescriptorBytes - nBytesRead) > 0) - m_pIO->Seek(pInfo->spAPEDescriptor->nDescriptorBytes - nBytesRead, FILE_CURRENT); - - // read the header - m_pIO->Read(&APEHeader, sizeof(APEHeader), &nBytesRead); - - if ((pInfo->spAPEDescriptor->nHeaderBytes - nBytesRead) > 0) - m_pIO->Seek(pInfo->spAPEDescriptor->nHeaderBytes - nBytesRead, FILE_CURRENT); - - // fill the APE info structure - pInfo->nVersion = int(pInfo->spAPEDescriptor->nVersion); - pInfo->nCompressionLevel = int(APEHeader.nCompressionLevel); - pInfo->nFormatFlags = int(APEHeader.nFormatFlags); - pInfo->nTotalFrames = int(APEHeader.nTotalFrames); - pInfo->nFinalFrameBlocks = int(APEHeader.nFinalFrameBlocks); - pInfo->nBlocksPerFrame = int(APEHeader.nBlocksPerFrame); - pInfo->nChannels = int(APEHeader.nChannels); - pInfo->nSampleRate = int(APEHeader.nSampleRate); - pInfo->nBitsPerSample = int(APEHeader.nBitsPerSample); - pInfo->nBytesPerSample = pInfo->nBitsPerSample / 8; - pInfo->nBlockAlign = pInfo->nBytesPerSample * pInfo->nChannels; - pInfo->nTotalBlocks = (APEHeader.nTotalFrames == 0) ? 0 : ((APEHeader.nTotalFrames - 1) * pInfo->nBlocksPerFrame) + APEHeader.nFinalFrameBlocks; - pInfo->nWAVHeaderBytes = (APEHeader.nFormatFlags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER) ? sizeof(WAVE_HEADER) : pInfo->spAPEDescriptor->nHeaderDataBytes; - pInfo->nWAVTerminatingBytes = pInfo->spAPEDescriptor->nTerminatingDataBytes; - pInfo->nWAVDataBytes = pInfo->nTotalBlocks * pInfo->nBlockAlign; - pInfo->nWAVTotalBytes = pInfo->nWAVDataBytes + pInfo->nWAVHeaderBytes + pInfo->nWAVTerminatingBytes; - pInfo->nAPETotalBytes = m_pIO->GetSize(); - pInfo->nLengthMS = int((double(pInfo->nTotalBlocks) * double(1000)) / double(pInfo->nSampleRate)); - pInfo->nAverageBitrate = (pInfo->nLengthMS <= 0) ? 0 : int((double(pInfo->nAPETotalBytes) * double(8)) / double(pInfo->nLengthMS)); - pInfo->nDecompressedBitrate = (pInfo->nBlockAlign * pInfo->nSampleRate * 8) / 1000; - pInfo->nSeekTableElements = pInfo->spAPEDescriptor->nSeekTableBytes / 4; - - // get the seek tables (really no reason to get the whole thing if there's extra) - pInfo->spSeekByteTable.Assign(new uint32 [pInfo->nSeekTableElements], TRUE); - if (pInfo->spSeekByteTable == NULL) { return ERROR_UNDEFINED; } - - m_pIO->Read((unsigned char *) pInfo->spSeekByteTable.GetPtr(), 4 * pInfo->nSeekTableElements, &nBytesRead); - - // get the wave header - if (!(APEHeader.nFormatFlags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER)) - { - pInfo->spWaveHeaderData.Assign(new unsigned char [pInfo->nWAVHeaderBytes], TRUE); - if (pInfo->spWaveHeaderData == NULL) { return ERROR_UNDEFINED; } - m_pIO->Read((unsigned char *) pInfo->spWaveHeaderData, pInfo->nWAVHeaderBytes, &nBytesRead); - } - - return ERROR_SUCCESS; -} - -int CAPEHeader::AnalyzeOld(APE_FILE_INFO * pInfo) -{ - // variable declares - unsigned int nBytesRead = 0; - - // read the MAC header from the file - APE_HEADER_OLD APEHeader; - m_pIO->Seek(pInfo->nJunkHeaderBytes, FILE_BEGIN); - m_pIO->Read((unsigned char *) &APEHeader, sizeof(APEHeader), &nBytesRead); - - // fail on 0 length APE files (catches non-finalized APE files) - if (APEHeader.nTotalFrames == 0) - return ERROR_UNDEFINED; - - int nPeakLevel = -1; - if (APEHeader.nFormatFlags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) - m_pIO->Read((unsigned char *) &nPeakLevel, 4, &nBytesRead); - - if (APEHeader.nFormatFlags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) - m_pIO->Read((unsigned char *) &pInfo->nSeekTableElements, 4, &nBytesRead); - else - pInfo->nSeekTableElements = APEHeader.nTotalFrames; - - // fill the APE info structure - pInfo->nVersion = int(APEHeader.nVersion); - pInfo->nCompressionLevel = int(APEHeader.nCompressionLevel); - pInfo->nFormatFlags = int(APEHeader.nFormatFlags); - pInfo->nTotalFrames = int(APEHeader.nTotalFrames); - pInfo->nFinalFrameBlocks = int(APEHeader.nFinalFrameBlocks); - pInfo->nBlocksPerFrame = ((APEHeader.nVersion >= 3900) || ((APEHeader.nVersion >= 3800) && (APEHeader.nCompressionLevel == COMPRESSION_LEVEL_EXTRA_HIGH))) ? 73728 : 9216; - if ((APEHeader.nVersion >= 3950)) pInfo->nBlocksPerFrame = 73728 * 4; - pInfo->nChannels = int(APEHeader.nChannels); - pInfo->nSampleRate = int(APEHeader.nSampleRate); - pInfo->nBitsPerSample = (pInfo->nFormatFlags & MAC_FORMAT_FLAG_8_BIT) ? 8 : ((pInfo->nFormatFlags & MAC_FORMAT_FLAG_24_BIT) ? 24 : 16); - pInfo->nBytesPerSample = pInfo->nBitsPerSample / 8; - pInfo->nBlockAlign = pInfo->nBytesPerSample * pInfo->nChannels; - pInfo->nTotalBlocks = (APEHeader.nTotalFrames == 0) ? 0 : ((APEHeader.nTotalFrames - 1) * pInfo->nBlocksPerFrame) + APEHeader.nFinalFrameBlocks; - pInfo->nWAVHeaderBytes = (APEHeader.nFormatFlags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER) ? sizeof(WAVE_HEADER) : APEHeader.nHeaderBytes; - pInfo->nWAVTerminatingBytes = int(APEHeader.nTerminatingBytes); - pInfo->nWAVDataBytes = pInfo->nTotalBlocks * pInfo->nBlockAlign; - pInfo->nWAVTotalBytes = pInfo->nWAVDataBytes + pInfo->nWAVHeaderBytes + pInfo->nWAVTerminatingBytes; - pInfo->nAPETotalBytes = m_pIO->GetSize(); - pInfo->nLengthMS = int((double(pInfo->nTotalBlocks) * double(1000)) / double(pInfo->nSampleRate)); - pInfo->nAverageBitrate = (pInfo->nLengthMS <= 0) ? 0 : int((double(pInfo->nAPETotalBytes) * double(8)) / double(pInfo->nLengthMS)); - pInfo->nDecompressedBitrate = (pInfo->nBlockAlign * pInfo->nSampleRate * 8) / 1000; - - // get the wave header - if (!(APEHeader.nFormatFlags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER)) - { - pInfo->spWaveHeaderData.Assign(new unsigned char [APEHeader.nHeaderBytes], TRUE); - if (pInfo->spWaveHeaderData == NULL) { return ERROR_UNDEFINED; } - m_pIO->Read((unsigned char *) pInfo->spWaveHeaderData, APEHeader.nHeaderBytes, &nBytesRead); - } - - // get the seek tables (really no reason to get the whole thing if there's extra) - pInfo->spSeekByteTable.Assign(new uint32 [pInfo->nSeekTableElements], TRUE); - if (pInfo->spSeekByteTable == NULL) { return ERROR_UNDEFINED; } - - m_pIO->Read((unsigned char *) pInfo->spSeekByteTable.GetPtr(), 4 * pInfo->nSeekTableElements, &nBytesRead); - - if (APEHeader.nVersion <= 3800) - { - pInfo->spSeekBitTable.Assign(new unsigned char [pInfo->nSeekTableElements], TRUE); - if (pInfo->spSeekBitTable == NULL) { return ERROR_UNDEFINED; } - - m_pIO->Read((unsigned char *) pInfo->spSeekBitTable, pInfo->nSeekTableElements, &nBytesRead); - } - - return ERROR_SUCCESS; -} \ No newline at end of file diff --git a/MAC_SDK/Source/MACLib/APEHeader.h b/MAC_SDK/Source/MACLib/APEHeader.h deleted file mode 100644 index 0446cd3..0000000 --- a/MAC_SDK/Source/MACLib/APEHeader.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef APE_HEADER_H -#define APE_HEADER_H - -/***************************************************************************************** -APE header that all APE files have in common (old and new) -*****************************************************************************************/ -struct APE_COMMON_HEADER -{ - char cID[4]; // should equal 'MAC ' - uint16 nVersion; // version number * 1000 (3.81 = 3810) -}; - -/***************************************************************************************** -APE header structure for old APE files (3.97 and earlier) -*****************************************************************************************/ -struct APE_HEADER_OLD -{ - char cID[4]; // should equal 'MAC ' - uint16 nVersion; // version number * 1000 (3.81 = 3810) - uint16 nCompressionLevel; // the compression level - uint16 nFormatFlags; // any format flags (for future use) - uint16 nChannels; // the number of channels (1 or 2) - uint32 nSampleRate; // the sample rate (typically 44100) - uint32 nHeaderBytes; // the bytes after the MAC header that compose the WAV header - uint32 nTerminatingBytes; // the bytes after that raw data (for extended info) - uint32 nTotalFrames; // the number of frames in the file - uint32 nFinalFrameBlocks; // the number of samples in the final frame -}; - -struct APE_FILE_INFO; -class CIO; - -/***************************************************************************************** -CAPEHeader - makes managing APE headers a little smoother (and the format change as of 3.98) -*****************************************************************************************/ -class CAPEHeader -{ - -public: - - CAPEHeader(CIO * pIO); - ~CAPEHeader(); - - int Analyze(APE_FILE_INFO * pInfo); - -protected: - - int AnalyzeCurrent(APE_FILE_INFO * pInfo); - int AnalyzeOld(APE_FILE_INFO * pInfo); - - int FindDescriptor(BOOL bSeek); - - CIO * m_pIO; -}; - -#endif // #ifndef APE_HEADER_H - diff --git a/MAC_SDK/Source/MACLib/APEInfo.cpp b/MAC_SDK/Source/MACLib/APEInfo.cpp deleted file mode 100644 index a62d08d..0000000 --- a/MAC_SDK/Source/MACLib/APEInfo.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/***************************************************************************************** -CAPEInfo: - -a class to make working with APE files and getting information about them simple -*****************************************************************************************/ -#include "All.h" -#include "APEInfo.h" -#include IO_HEADER_FILE -#include "APECompress.h" -#include "APEHeader.h" - -/***************************************************************************************** -Construction -*****************************************************************************************/ -#ifdef IO_CLASS_NAME -CAPEInfo::CAPEInfo(int * pErrorCode, const wchar_t * pFilename, CAPETag * pTag, bool fReadOnly) -{ - *pErrorCode = ERROR_SUCCESS; - CloseFile(); - - // open the file - m_spIO.Assign(new IO_CLASS_NAME); - - if (m_spIO->Open(pFilename, fReadOnly) != 0) - { - CloseFile(); - *pErrorCode = ERROR_INVALID_INPUT_FILE; - return; - } - - // get the file information - if (GetFileInformation(TRUE) != 0) - { - CloseFile(); - *pErrorCode = ERROR_INVALID_INPUT_FILE; - return; - } - -#ifndef NO_TAG - // get the tag (do this second so that we don't do it on failure) - if (pTag == NULL) - { - // we don't want to analyze right away for non-local files - // since a single I/O object is shared, we can't tag and read at the same time (i.e. in multiple threads) - BOOL bAnalyzeNow = TRUE; - if ((wcsnicmp(pFilename, L"http://", 7) == 0) || (wcsnicmp(pFilename, L"m01p://", 7) == 0)) - bAnalyzeNow = FALSE; - - m_spAPETag.Assign(new CAPETag(m_spIO, bAnalyzeNow)); - } - else - { - m_spAPETag.Assign(pTag); - } -#endif -} -#endif - -CAPEInfo::CAPEInfo(int * pErrorCode, CIO * pIO, CAPETag * pTag) -{ - *pErrorCode = ERROR_SUCCESS; - CloseFile(); - - m_spIO.Assign(pIO, FALSE, FALSE); - - // get the file information - if (GetFileInformation(TRUE) != 0) - { - CloseFile(); - *pErrorCode = ERROR_INVALID_INPUT_FILE; - return; - } - -#ifndef NO_TAG - // get the tag (do this second so that we don't do it on failure) - if (pTag == NULL) - m_spAPETag.Assign(new CAPETag(m_spIO, FALSE)); - else - m_spAPETag.Assign(pTag); -#endif -} - - -/***************************************************************************************** -Destruction -*****************************************************************************************/ -CAPEInfo::~CAPEInfo() -{ - CloseFile(); -} - -/***************************************************************************************** -Close the file -*****************************************************************************************/ -int CAPEInfo::CloseFile() -{ - m_spIO.Delete(); - m_APEFileInfo.spWaveHeaderData.Delete(); - m_APEFileInfo.spSeekBitTable.Delete(); - m_APEFileInfo.spSeekByteTable.Delete(); - m_APEFileInfo.spAPEDescriptor.Delete(); - -#ifndef NO_TAG - m_spAPETag.Delete(); -#endif - - // re-initialize variables - m_APEFileInfo.nSeekTableElements = 0; - m_bHasFileInformationLoaded = FALSE; - - return ERROR_SUCCESS; -} - -/***************************************************************************************** -Get the file information about the file -*****************************************************************************************/ -int CAPEInfo::GetFileInformation(BOOL bGetTagInformation) -{ - // quit if there is no simple file - if (m_spIO == NULL) { return -1; } - - // quit if the file information has already been loaded - if (m_bHasFileInformationLoaded) { return ERROR_SUCCESS; } - - // use a CAPEHeader class to help us analyze the file - CAPEHeader APEHeader(m_spIO); - int nRetVal = APEHeader.Analyze(&m_APEFileInfo); - - // update our internal state - if (nRetVal == ERROR_SUCCESS) - m_bHasFileInformationLoaded = TRUE; - - // return - return nRetVal; -} - -/***************************************************************************************** -Primary query function -*****************************************************************************************/ -int CAPEInfo::GetInfo(APE_DECOMPRESS_FIELDS Field, int nParam1, int nParam2) -{ - int nRetVal = -1; - - switch (Field) - { - case APE_INFO_FILE_VERSION: - nRetVal = m_APEFileInfo.nVersion; - break; - case APE_INFO_COMPRESSION_LEVEL: - nRetVal = m_APEFileInfo.nCompressionLevel; - break; - case APE_INFO_FORMAT_FLAGS: - nRetVal = m_APEFileInfo.nFormatFlags; - break; - case APE_INFO_SAMPLE_RATE: - nRetVal = m_APEFileInfo.nSampleRate; - break; - case APE_INFO_BITS_PER_SAMPLE: - nRetVal = m_APEFileInfo.nBitsPerSample; - break; - case APE_INFO_BYTES_PER_SAMPLE: - nRetVal = m_APEFileInfo.nBytesPerSample; - break; - case APE_INFO_CHANNELS: - nRetVal = m_APEFileInfo.nChannels; - break; - case APE_INFO_BLOCK_ALIGN: - nRetVal = m_APEFileInfo.nBlockAlign; - break; - case APE_INFO_BLOCKS_PER_FRAME: - nRetVal = m_APEFileInfo.nBlocksPerFrame; - break; - case APE_INFO_FINAL_FRAME_BLOCKS: - nRetVal = m_APEFileInfo.nFinalFrameBlocks; - break; - case APE_INFO_TOTAL_FRAMES: - nRetVal = m_APEFileInfo.nTotalFrames; - break; - case APE_INFO_WAV_HEADER_BYTES: - nRetVal = m_APEFileInfo.nWAVHeaderBytes; - break; - case APE_INFO_WAV_TERMINATING_BYTES: - nRetVal = m_APEFileInfo.nWAVTerminatingBytes; - break; - case APE_INFO_WAV_DATA_BYTES: - nRetVal = m_APEFileInfo.nWAVDataBytes; - break; - case APE_INFO_WAV_TOTAL_BYTES: - nRetVal = m_APEFileInfo.nWAVTotalBytes; - break; - case APE_INFO_APE_TOTAL_BYTES: - nRetVal = m_APEFileInfo.nAPETotalBytes; - break; - case APE_INFO_TOTAL_BLOCKS: - nRetVal = m_APEFileInfo.nTotalBlocks; - break; - case APE_INFO_LENGTH_MS: - nRetVal = m_APEFileInfo.nLengthMS; - break; - case APE_INFO_AVERAGE_BITRATE: - nRetVal = m_APEFileInfo.nAverageBitrate; - break; - case APE_INFO_FRAME_BITRATE: - { - int nFrame = nParam1; - - nRetVal = 0; - - int nFrameBytes = GetInfo(APE_INFO_FRAME_BYTES, nFrame); - int nFrameBlocks = GetInfo(APE_INFO_FRAME_BLOCKS, nFrame); - if ((nFrameBytes > 0) && (nFrameBlocks > 0) && m_APEFileInfo.nSampleRate > 0) - { - int nFrameMS = (nFrameBlocks * 1000) / m_APEFileInfo.nSampleRate; - if (nFrameMS != 0) - { - nRetVal = (nFrameBytes * 8) / nFrameMS; - } - } - break; - } - case APE_INFO_DECOMPRESSED_BITRATE: - nRetVal = m_APEFileInfo.nDecompressedBitrate; - break; - case APE_INFO_PEAK_LEVEL: - nRetVal = -1; // no longer supported - break; - case APE_INFO_SEEK_BIT: - { - int nFrame = nParam1; - if (GET_FRAMES_START_ON_BYTES_BOUNDARIES(this)) - { - nRetVal = 0; - } - else - { - if (nFrame < 0 || nFrame >= m_APEFileInfo.nTotalFrames) - nRetVal = 0; - else - nRetVal = m_APEFileInfo.spSeekBitTable[nFrame]; - } - break; - } - case APE_INFO_SEEK_BYTE: - { - int nFrame = nParam1; - if (nFrame < 0 || nFrame >= m_APEFileInfo.nTotalFrames) - nRetVal = 0; - else - nRetVal = m_APEFileInfo.spSeekByteTable[nFrame] + m_APEFileInfo.nJunkHeaderBytes; - break; - } - case APE_INFO_WAV_HEADER_DATA: - { - char * pBuffer = (char *) nParam1; - int nMaxBytes = nParam2; - - if (m_APEFileInfo.nFormatFlags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER) - { - if (sizeof(WAVE_HEADER) > nMaxBytes) - { - nRetVal = -1; - } - else - { - WAVEFORMATEX wfeFormat; GetInfo(APE_INFO_WAVEFORMATEX, (int) &wfeFormat, 0); - WAVE_HEADER WAVHeader; FillWaveHeader(&WAVHeader, m_APEFileInfo.nWAVDataBytes, &wfeFormat, - m_APEFileInfo.nWAVTerminatingBytes); - memcpy(pBuffer, &WAVHeader, sizeof(WAVE_HEADER)); - nRetVal = 0; - } - } - else - { - if (m_APEFileInfo.nWAVHeaderBytes > nMaxBytes) - { - nRetVal = -1; - } - else - { - memcpy(pBuffer, m_APEFileInfo.spWaveHeaderData, m_APEFileInfo.nWAVHeaderBytes); - nRetVal = 0; - } - } - break; - } -#ifndef NO_TAG - case APE_INFO_WAV_TERMINATING_DATA: - { - char * pBuffer = (char *) nParam1; - int nMaxBytes = nParam2; - - if (m_APEFileInfo.nWAVTerminatingBytes > nMaxBytes) - { - nRetVal = -1; - } - else - { - if (m_APEFileInfo.nWAVTerminatingBytes > 0) - { - // variables - int nOriginalFileLocation = m_spIO->GetPosition(); - unsigned int nBytesRead = 0; - - // check for a tag - m_spIO->Seek(-(m_spAPETag->GetTagBytes() + m_APEFileInfo.nWAVTerminatingBytes), FILE_END); - m_spIO->Read(pBuffer, m_APEFileInfo.nWAVTerminatingBytes, &nBytesRead); - - // restore the file pointer - m_spIO->Seek(nOriginalFileLocation, FILE_BEGIN); - } - nRetVal = 0; - } - break; - } -#endif - case APE_INFO_WAVEFORMATEX: - { - WAVEFORMATEX * pWaveFormatEx = (WAVEFORMATEX *) nParam1; - FillWaveFormatEx(pWaveFormatEx, m_APEFileInfo.nSampleRate, m_APEFileInfo.nBitsPerSample, m_APEFileInfo.nChannels); - nRetVal = 0; - break; - } - case APE_INFO_IO_SOURCE: - nRetVal = (int) m_spIO.GetPtr(); - break; -#ifndef NO_TAG - case APE_INFO_FRAME_BYTES: - { - int nFrame = nParam1; - - // bound-check the frame index - if ((nFrame < 0) || (nFrame >= m_APEFileInfo.nTotalFrames)) - { - nRetVal = -1; - } - else - { - if (nFrame != (m_APEFileInfo.nTotalFrames - 1)) - nRetVal = GetInfo(APE_INFO_SEEK_BYTE, nFrame + 1) - GetInfo(APE_INFO_SEEK_BYTE, nFrame); - else - nRetVal = m_spIO->GetSize() - m_spAPETag->GetTagBytes() - m_APEFileInfo.nWAVTerminatingBytes - GetInfo(APE_INFO_SEEK_BYTE, nFrame); - } - break; - } -#endif - case APE_INFO_FRAME_BLOCKS: - { - int nFrame = nParam1; - - // bound-check the frame index - if ((nFrame < 0) || (nFrame >= m_APEFileInfo.nTotalFrames)) - { - nRetVal = -1; - } - else - { - if (nFrame != (m_APEFileInfo.nTotalFrames - 1)) - nRetVal = m_APEFileInfo.nBlocksPerFrame; - else - nRetVal = m_APEFileInfo.nFinalFrameBlocks; - } - break; - } -#ifndef NO_TAG - case APE_INFO_TAG: - nRetVal = (int) m_spAPETag.GetPtr(); - break; -#endif - case APE_INTERNAL_INFO: - nRetVal = (int) &m_APEFileInfo; - break; - } - - return nRetVal; -} \ No newline at end of file diff --git a/MAC_SDK/Source/MACLib/APEInfo.h b/MAC_SDK/Source/MACLib/APEInfo.h deleted file mode 100644 index b1865fe..0000000 --- a/MAC_SDK/Source/MACLib/APEInfo.h +++ /dev/null @@ -1,106 +0,0 @@ -/***************************************************************************************** -APEInfo.h -Copyright (C) 2000 by Matthew T. Ashland All Rights Reserved. - -Simple method for working with APE files... it encapsulates reading, writing and getting -file information. Just create a CAPEInfo class, call OpenFile(), and use the class methods -to do whatever you need... the destructor will take care of any cleanup - -Notes: - -Most all functions return 0 upon success, and some error code (other than 0) on - failure. However, all of the file functions that are wrapped from the Win32 API - return 0 on failure and some other number on success. This applies to ReadFile, - WriteFile, SetFilePointer, etc... - -WARNING: - -This class driven system for using Monkey's Audio is still in development, so - I can't make any guarantees that the classes and libraries won't change before - everything gets finalized. Use them at your own risk -*****************************************************************************************/ - -#ifndef APE_APEINFO_H -#define APE_APEINFO_H - -#include "IO.h" -#ifndef NO_TAG -#include "APETag.h" -#else -#define CAPETag void -#endif -#include "MACLib.h" - -/***************************************************************************************** -APE_FILE_INFO - structure which describes most aspects of an APE file -(used internally for speed and ease) -*****************************************************************************************/ -struct APE_FILE_INFO -{ - int nVersion; // file version number * 1000 (3.93 = 3930) - int nCompressionLevel; // the compression level - int nFormatFlags; // format flags - int nTotalFrames; // the total number frames (frames are used internally) - int nBlocksPerFrame; // the samples in a frame (frames are used internally) - int nFinalFrameBlocks; // the number of samples in the final frame - int nChannels; // audio channels - int nSampleRate; // audio samples per second - int nBitsPerSample; // audio bits per sample - int nBytesPerSample; // audio bytes per sample - int nBlockAlign; // audio block align (channels * bytes per sample) - int nWAVHeaderBytes; // header bytes of the original WAV - int nWAVDataBytes; // data bytes of the original WAV - int nWAVTerminatingBytes; // terminating bytes of the original WAV - int nWAVTotalBytes; // total bytes of the original WAV - int nAPETotalBytes; // total bytes of the APE file - int nTotalBlocks; // the total number audio blocks - int nLengthMS; // the length in milliseconds - int nAverageBitrate; // the kbps (i.e. 637 kpbs) - int nDecompressedBitrate; // the kbps of the decompressed audio (i.e. 1440 kpbs for CD audio) - int nJunkHeaderBytes; // used for ID3v2, etc. - int nSeekTableElements; // the number of elements in the seek table(s) - - CSmartPtr spSeekByteTable; // the seek table (byte) - CSmartPtr spSeekBitTable; // the seek table (bits -- legacy) - CSmartPtr spWaveHeaderData; // the pre-audio header data - CSmartPtr spAPEDescriptor; // the descriptor (only with newer files) -}; - -/***************************************************************************************** -Helper macros (sort of hacky) -*****************************************************************************************/ -#define GET_USES_CRC(APE_INFO) (((APE_INFO)->GetInfo(APE_INFO_FORMAT_FLAGS) & MAC_FORMAT_FLAG_CRC) ? TRUE : FALSE) -#define GET_FRAMES_START_ON_BYTES_BOUNDARIES(APE_INFO) (((APE_INFO)->GetInfo(APE_INFO_FILE_VERSION) > 3800) ? TRUE : FALSE) -#define GET_USES_SPECIAL_FRAMES(APE_INFO) (((APE_INFO)->GetInfo(APE_INFO_FILE_VERSION) > 3820) ? TRUE : FALSE) -#define GET_IO(APE_INFO) ((CIO *) (APE_INFO)->GetInfo(APE_INFO_IO_SOURCE)) -#define GET_TAG(APE_INFO) ((CAPETag *) (APE_INFO)->GetInfo(APE_INFO_TAG)) - -/***************************************************************************************** -CAPEInfo - use this for all work with APE files -*****************************************************************************************/ -class CAPEInfo -{ -public: - - // construction and destruction - CAPEInfo(int * pErrorCode, const wchar_t * pFilename, CAPETag * pTag = NULL, bool fReadOnly = 0); - CAPEInfo(int * pErrorCode, CIO * pIO, CAPETag * pTag = NULL); - virtual ~CAPEInfo(); - - // query for information - int GetInfo(APE_DECOMPRESS_FIELDS Field, int nParam1 = 0, int nParam2 = 0); - -private: - - // internal functions - int GetFileInformation(BOOL bGetTagInformation = TRUE); - int CloseFile(); - - // internal variables - BOOL m_bHasFileInformationLoaded; - CSmartPtr m_spIO; -#ifndef NO_TAG - CSmartPtr m_spAPETag; -#endif - APE_FILE_INFO m_APEFileInfo; -}; - -#endif // #ifndef APE_APEINFO_H diff --git a/MAC_SDK/Source/MACLib/APELink.cpp b/MAC_SDK/Source/MACLib/APELink.cpp deleted file mode 100644 index 4606740..0000000 --- a/MAC_SDK/Source/MACLib/APELink.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "All.h" -#include "APELink.h" -#include "CharacterHelper.h" -#include IO_HEADER_FILE - -#define APE_LINK_HEADER "[Monkey's Audio Image Link File]" -#define APE_LINK_IMAGE_FILE_TAG "Image File=" -#define APE_LINK_START_BLOCK_TAG "Start Block=" -#define APE_LINK_FINISH_BLOCK_TAG "Finish Block=" - -CAPELink::CAPELink(const str_utf16 * pFilename) -{ - // empty - m_bIsLinkFile = FALSE; - m_nStartBlock = 0; - m_nFinishBlock = 0; - m_cImageFilename[0] = 0; - - // open the file - IO_CLASS_NAME ioLinkFile; - if (ioLinkFile.Open(pFilename) == ERROR_SUCCESS) - { - // create a buffer - CSmartPtr spBuffer(new char [1024], TRUE); - - // fill the buffer from the file and null terminate it - unsigned int nBytesRead = 0; - ioLinkFile.Read(spBuffer.GetPtr(), 1023, &nBytesRead); - spBuffer[nBytesRead] = 0; - - // call the other constructor (uses a buffer instead of opening the file) - ParseData(spBuffer, pFilename); - } -} - -CAPELink::CAPELink(const char * pData, const str_utf16 * pFilename) -{ - ParseData(pData, pFilename); -} - -CAPELink::~CAPELink() -{ -} - -void CAPELink::ParseData(const char * pData, const str_utf16 * pFilename) -{ - // empty - m_bIsLinkFile = FALSE; - m_nStartBlock = 0; - m_nFinishBlock = 0; - m_cImageFilename[0] = 0; - - if (pData != NULL) - { - // parse out the information - char * pHeader = (char*)strstr(pData, APE_LINK_HEADER); - char * pImageFile = (char*)strstr(pData, APE_LINK_IMAGE_FILE_TAG); - char * pStartBlock = (char*)strstr(pData, APE_LINK_START_BLOCK_TAG); - char * pFinishBlock = (char*)strstr(pData, APE_LINK_FINISH_BLOCK_TAG); - - if (pHeader && pImageFile && pStartBlock && pFinishBlock) - { - if ((_strnicmp(pHeader, APE_LINK_HEADER, strlen(APE_LINK_HEADER)) == 0) && - (_strnicmp(pImageFile, APE_LINK_IMAGE_FILE_TAG, strlen(APE_LINK_IMAGE_FILE_TAG)) == 0) && - (_strnicmp(pStartBlock, APE_LINK_START_BLOCK_TAG, strlen(APE_LINK_START_BLOCK_TAG)) == 0) && - (_strnicmp(pFinishBlock, APE_LINK_FINISH_BLOCK_TAG, strlen(APE_LINK_FINISH_BLOCK_TAG)) == 0)) - { - // get the start and finish blocks - m_nStartBlock = atoi(&pStartBlock[strlen(APE_LINK_START_BLOCK_TAG)]); - m_nFinishBlock = atoi(&pFinishBlock[strlen(APE_LINK_FINISH_BLOCK_TAG)]); - - // get the path - char cImageFile[MAX_PATH + 1]; int nIndex = 0; - char * pImageCharacter = &pImageFile[strlen(APE_LINK_IMAGE_FILE_TAG)]; - while ((*pImageCharacter != 0) && (*pImageCharacter != '\r') && (*pImageCharacter != '\n')) - cImageFile[nIndex++] = *pImageCharacter++; - cImageFile[nIndex] = 0; - - CSmartPtr spImageFileUTF16(GetUTF16FromUTF8((UCHAR *) cImageFile), TRUE); - - // process the path - if (wcsrchr(spImageFileUTF16, '\\') == NULL) - { - str_utf16 cImagePath[MAX_PATH + 1]; - wcscpy(cImagePath, pFilename); - wcscpy(wcsrchr(cImagePath, '\\') + 1, spImageFileUTF16); - wcscpy(m_cImageFilename, cImagePath); - } - else - { - wcscpy(m_cImageFilename, spImageFileUTF16); - } - - // this is a valid link file - m_bIsLinkFile = TRUE; - } - } - } -} - -int CAPELink::GetStartBlock() -{ - return m_nStartBlock; -} - -int CAPELink::GetFinishBlock() -{ - return m_nFinishBlock; -} - -const str_utf16 * CAPELink::GetImageFilename() -{ - return m_cImageFilename; -} - -BOOL CAPELink::GetIsLinkFile() -{ - return m_bIsLinkFile; -} - diff --git a/MAC_SDK/Source/MACLib/APELink.h b/MAC_SDK/Source/MACLib/APELink.h deleted file mode 100644 index 390b963..0000000 --- a/MAC_SDK/Source/MACLib/APELink.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef APE_APELINK_H -#define APE_APELINK_H - -#include "IO.h" -#include "APEInfo.h" - -class CAPELink -{ -public: - - CAPELink(const str_utf16 * pFilename); - CAPELink(const char * pData, const str_utf16 * pFilename); - ~CAPELink(); - - BOOL GetIsLinkFile(); - int GetStartBlock(); - int GetFinishBlock(); - const wchar_t * GetImageFilename(); - -protected: - - BOOL m_bIsLinkFile; - int m_nStartBlock; - int m_nFinishBlock; - str_utf16 m_cImageFilename[MAX_PATH]; - - void ParseData(const char * pData, const str_utf16 * pFilename); -}; - -#endif // #ifndef APE_APELINK_H diff --git a/MAC_SDK/Source/MACLib/APESimple.cpp b/MAC_SDK/Source/MACLib/APESimple.cpp deleted file mode 100644 index 2420021..0000000 --- a/MAC_SDK/Source/MACLib/APESimple.cpp +++ /dev/null @@ -1,430 +0,0 @@ -#include "All.h" -#include "APEInfo.h" -#include "APECompress.h" -#include "APEDecompress.h" -#include "WAVInputSource.h" -#include IO_HEADER_FILE -#include "MACProgressHelper.h" -#include "GlobalFunctions.h" -#include "MD5.h" -#include "CharacterHelper.h" - -#define UNMAC_DECODER_OUTPUT_NONE 0 -#define UNMAC_DECODER_OUTPUT_WAV 1 -#define UNMAC_DECODER_OUTPUT_APE 2 - -#define BLOCKS_PER_DECODE 9216 - -int DecompressCore(const str_utf16 * pInputFilename, const str_utf16 * pOutputFilename, int nOutputMode, int nCompressionLevel, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag); - -/***************************************************************************************** -ANSI wrappers -*****************************************************************************************/ -int __stdcall CompressFile(const str_ansi * pInputFilename, const str_ansi * pOutputFilename, int nCompressionLevel, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag) -{ - CSmartPtr spInputFile(GetUTF16FromANSI(pInputFilename), TRUE); - CSmartPtr spOutputFile(GetUTF16FromANSI(pOutputFilename), TRUE); - return CompressFileW(spInputFile, spOutputFile, nCompressionLevel, pPercentageDone, ProgressCallback, pKillFlag); -} - -int __stdcall DecompressFile(const str_ansi * pInputFilename, const str_ansi * pOutputFilename, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag) -{ - CSmartPtr spInputFile(GetUTF16FromANSI(pInputFilename), TRUE); - CSmartPtr spOutputFile(GetUTF16FromANSI(pOutputFilename), TRUE); - return DecompressFileW(spInputFile, pOutputFilename ? spOutputFile : NULL, pPercentageDone, ProgressCallback, pKillFlag); -} - -int __stdcall ConvertFile(const str_ansi * pInputFilename, const str_ansi * pOutputFilename, int nCompressionLevel, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag) -{ - CSmartPtr spInputFile(GetUTF16FromANSI(pInputFilename), TRUE); - CSmartPtr spOutputFile(GetUTF16FromANSI(pOutputFilename), TRUE); - return ConvertFileW(spInputFile, spOutputFile, nCompressionLevel, pPercentageDone, ProgressCallback, pKillFlag); -} - -int __stdcall VerifyFile(const str_ansi * pInputFilename, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag, BOOL bQuickVerifyIfPossible) -{ - CSmartPtr spInputFile(GetUTF16FromANSI(pInputFilename), TRUE); - return VerifyFileW(spInputFile, pPercentageDone, ProgressCallback, pKillFlag, FALSE); -} - -/***************************************************************************************** -Compress file -*****************************************************************************************/ -int __stdcall CompressFileW(const str_utf16 * pInputFilename, const str_utf16 * pOutputFilename, int nCompressionLevel, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag) -{ - // declare the variables - int nFunctionRetVal = ERROR_SUCCESS; - WAVEFORMATEX WaveFormatEx; - CSmartPtr spMACProgressHelper; - CSmartPtr spBuffer; - CSmartPtr spAPECompress; - - try - { - // create the input source - int nRetVal = ERROR_UNDEFINED; - int nAudioBlocks = 0; int nHeaderBytes = 0; int nTerminatingBytes = 0; - CSmartPtr spInputSource(CreateInputSource(pInputFilename, &WaveFormatEx, &nAudioBlocks, - &nHeaderBytes, &nTerminatingBytes, &nRetVal)); - - if ((spInputSource == NULL) || (nRetVal != ERROR_SUCCESS)) - throw nRetVal; - - // create the compressor - spAPECompress.Assign(CreateIAPECompress()); - if (spAPECompress == NULL) throw ERROR_UNDEFINED; - - // figure the audio bytes - int nAudioBytes = nAudioBlocks * WaveFormatEx.nBlockAlign; - - // start the encoder - if (nHeaderBytes > 0) spBuffer.Assign(new unsigned char [nHeaderBytes], TRUE); - THROW_ON_ERROR(spInputSource->GetHeaderData(spBuffer.GetPtr())) - THROW_ON_ERROR(spAPECompress->Start(pOutputFilename, &WaveFormatEx, nAudioBytes, - nCompressionLevel, spBuffer.GetPtr(), nHeaderBytes)); - - spBuffer.Delete(); - - // set-up the progress - spMACProgressHelper.Assign(new CMACProgressHelper(nAudioBytes, pPercentageDone, ProgressCallback, pKillFlag)); - - // master loop - int nBytesLeft = nAudioBytes; - - while (nBytesLeft > 0) - { - int nBytesAdded = 0; - THROW_ON_ERROR(spAPECompress->AddDataFromInputSource(spInputSource.GetPtr(), nBytesLeft, &nBytesAdded)) - - nBytesLeft -= nBytesAdded; - - // update the progress - spMACProgressHelper->UpdateProgress(nAudioBytes - nBytesLeft); - - // process the kill flag - if (spMACProgressHelper->ProcessKillFlag(TRUE) != ERROR_SUCCESS) - throw(ERROR_USER_STOPPED_PROCESSING); - } - - // finalize the file - if (nTerminatingBytes > 0) spBuffer.Assign(new unsigned char [nTerminatingBytes], TRUE); - THROW_ON_ERROR(spInputSource->GetTerminatingData(spBuffer.GetPtr())); - THROW_ON_ERROR(spAPECompress->Finish(spBuffer.GetPtr(), nTerminatingBytes, nTerminatingBytes)) - - // update the progress to 100% - spMACProgressHelper->UpdateProgressComplete(); - } - catch(int nErrorCode) - { - nFunctionRetVal = (nErrorCode == 0) ? ERROR_UNDEFINED : nErrorCode; - } - catch(...) - { - nFunctionRetVal = ERROR_UNDEFINED; - } - - // kill the compressor if we failed - if ((nFunctionRetVal != 0) && (spAPECompress != NULL)) - spAPECompress->Kill(); - - // return - return nFunctionRetVal; -} - - -/***************************************************************************************** -Verify file -*****************************************************************************************/ -int __stdcall VerifyFileW(const str_utf16 * pInputFilename, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag, BOOL bQuickVerifyIfPossible) -{ - // error check the function parameters - if (pInputFilename == NULL) - { - return ERROR_INVALID_FUNCTION_PARAMETER; - } - - - // return value - int nRetVal = ERROR_UNDEFINED; - - // see if we can quick verify - if (bQuickVerifyIfPossible) - { - CSmartPtr spAPEDecompress; - try - { - int nFunctionRetVal = ERROR_SUCCESS; - - spAPEDecompress.Assign(CreateIAPEDecompress(pInputFilename, &nFunctionRetVal)); - if (spAPEDecompress == NULL || nFunctionRetVal != ERROR_SUCCESS) throw(nFunctionRetVal); - - APE_FILE_INFO * pInfo = (APE_FILE_INFO *) spAPEDecompress->GetInfo(APE_INTERNAL_INFO); - if ((pInfo->nVersion < 3980) || (pInfo->spAPEDescriptor == NULL)) - throw(ERROR_UPSUPPORTED_FILE_VERSION); - } - catch(...) - { - bQuickVerifyIfPossible = FALSE; - } - } - - // if we can and should quick verify, then do it - if (bQuickVerifyIfPossible) - { - // variable declares - int nFunctionRetVal = ERROR_SUCCESS; - unsigned int nBytesRead = 0; - CSmartPtr spAPEDecompress; - - // run the quick verify - try - { - spAPEDecompress.Assign(CreateIAPEDecompress(pInputFilename, &nFunctionRetVal)); - if (spAPEDecompress == NULL || nFunctionRetVal != ERROR_SUCCESS) throw(nFunctionRetVal); - - CMD5Helper MD5Helper; - - CIO * pIO = GET_IO(spAPEDecompress); - APE_FILE_INFO * pInfo = (APE_FILE_INFO *) spAPEDecompress->GetInfo(APE_INTERNAL_INFO); - - if ((pInfo->nVersion < 3980) || (pInfo->spAPEDescriptor == NULL)) - throw(ERROR_UPSUPPORTED_FILE_VERSION); - - int nHead = pInfo->nJunkHeaderBytes + pInfo->spAPEDescriptor->nDescriptorBytes; - int nStart = nHead + pInfo->spAPEDescriptor->nHeaderBytes + pInfo->spAPEDescriptor->nSeekTableBytes; - - pIO->Seek(nHead, FILE_BEGIN); - int nHeadBytes = nStart - nHead; - CSmartPtr spHeadBuffer(new unsigned char [nHeadBytes], TRUE); - if ((pIO->Read(spHeadBuffer, nHeadBytes, &nBytesRead) != ERROR_SUCCESS) || (nHeadBytes != int(nBytesRead))) - throw(ERROR_IO_READ); - - int nBytesLeft = pInfo->spAPEDescriptor->nHeaderDataBytes + pInfo->spAPEDescriptor->nAPEFrameDataBytes + pInfo->spAPEDescriptor->nTerminatingDataBytes; - CSmartPtr spBuffer(new unsigned char [16384], TRUE); - nBytesRead = 1; - while ((nBytesLeft > 0) && (nBytesRead > 0)) - { - int nBytesToRead = min(16384, nBytesLeft); - if (pIO->Read(spBuffer, nBytesToRead, &nBytesRead) != ERROR_SUCCESS) - throw(ERROR_IO_READ); - - MD5Helper.AddData(spBuffer, nBytesRead); - nBytesLeft -= nBytesRead; - } - - if (nBytesLeft != 0) - throw(ERROR_IO_READ); - - MD5Helper.AddData(spHeadBuffer, nHeadBytes); - - unsigned char cResult[16]; - MD5Helper.GetResult(cResult); - - if (memcmp(cResult, pInfo->spAPEDescriptor->cFileMD5, 16) != 0) - nFunctionRetVal = ERROR_INVALID_CHECKSUM; - - } - catch(int nErrorCode) - { - nFunctionRetVal = (nErrorCode == 0) ? ERROR_UNDEFINED : nErrorCode; - } - catch(...) - { - nFunctionRetVal = ERROR_UNDEFINED; - } - - // return value - nRetVal = nFunctionRetVal; - } - else - { - nRetVal = DecompressCore(pInputFilename, NULL, UNMAC_DECODER_OUTPUT_NONE, -1, pPercentageDone, ProgressCallback, pKillFlag); - } - - - return nRetVal; -} - -/***************************************************************************************** -Decompress file -*****************************************************************************************/ -int __stdcall DecompressFileW(const str_utf16 * pInputFilename, const str_utf16 * pOutputFilename, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag) -{ - if (pOutputFilename == NULL) - return VerifyFileW(pInputFilename, pPercentageDone, ProgressCallback, pKillFlag); - else - return DecompressCore(pInputFilename, pOutputFilename, UNMAC_DECODER_OUTPUT_WAV, -1, pPercentageDone, ProgressCallback, pKillFlag); -} - -/***************************************************************************************** -Convert file -*****************************************************************************************/ -int __stdcall ConvertFileW(const str_utf16 * pInputFilename, const str_utf16 * pOutputFilename, int nCompressionLevel, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag) -{ - return DecompressCore(pInputFilename, pOutputFilename, UNMAC_DECODER_OUTPUT_APE, nCompressionLevel, pPercentageDone, ProgressCallback, pKillFlag); -} - -/***************************************************************************************** -Decompress a file using the specified output method -*****************************************************************************************/ -int DecompressCore(const str_utf16 * pInputFilename, const str_utf16 * pOutputFilename, int nOutputMode, int nCompressionLevel, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag) -{ - // error check the function parameters - if (pInputFilename == NULL) - { - return ERROR_INVALID_FUNCTION_PARAMETER; - } - - // variable declares - int nFunctionRetVal = ERROR_SUCCESS; - CSmartPtr spioOutput; - CSmartPtr spAPECompress; - CSmartPtr spAPEDecompress; - CSmartPtr spTempBuffer; - CSmartPtr spMACProgressHelper; - WAVEFORMATEX wfeInput; - - try - { - // create the decoder - spAPEDecompress.Assign(CreateIAPEDecompress(pInputFilename, &nFunctionRetVal)); - if (spAPEDecompress == NULL || nFunctionRetVal != ERROR_SUCCESS) throw(nFunctionRetVal); - - // get the input format - THROW_ON_ERROR(spAPEDecompress->GetInfo(APE_INFO_WAVEFORMATEX, (int) &wfeInput)) - - // allocate space for the header - spTempBuffer.Assign(new unsigned char [spAPEDecompress->GetInfo(APE_INFO_WAV_HEADER_BYTES)], TRUE); - if (spTempBuffer == NULL) throw(ERROR_INSUFFICIENT_MEMORY); - - // get the header - THROW_ON_ERROR(spAPEDecompress->GetInfo(APE_INFO_WAV_HEADER_DATA, (int) spTempBuffer.GetPtr(), spAPEDecompress->GetInfo(APE_INFO_WAV_HEADER_BYTES))); - - // initialize the output - if (nOutputMode == UNMAC_DECODER_OUTPUT_WAV) - { - // create the file - spioOutput.Assign(new IO_CLASS_NAME); THROW_ON_ERROR(spioOutput->Create(pOutputFilename)) - - // output the header - THROW_ON_ERROR(WriteSafe(spioOutput, spTempBuffer, spAPEDecompress->GetInfo(APE_INFO_WAV_HEADER_BYTES))); - } - else if (nOutputMode == UNMAC_DECODER_OUTPUT_APE) - { - // quit if there is nothing to do - if (spAPEDecompress->GetInfo(APE_INFO_FILE_VERSION) == MAC_VERSION_NUMBER && spAPEDecompress->GetInfo(APE_INFO_COMPRESSION_LEVEL) == nCompressionLevel) - throw(ERROR_SKIPPED); - - // create and start the compressor - spAPECompress.Assign(CreateIAPECompress()); - THROW_ON_ERROR(spAPECompress->Start(pOutputFilename, &wfeInput, spAPEDecompress->GetInfo(APE_DECOMPRESS_TOTAL_BLOCKS) * spAPEDecompress->GetInfo(APE_INFO_BLOCK_ALIGN), - nCompressionLevel, spTempBuffer, spAPEDecompress->GetInfo(APE_INFO_WAV_HEADER_BYTES))) - } - - // allocate space for decompression - spTempBuffer.Assign(new unsigned char [spAPEDecompress->GetInfo(APE_INFO_BLOCK_ALIGN) * BLOCKS_PER_DECODE], TRUE); - if (spTempBuffer == NULL) throw(ERROR_INSUFFICIENT_MEMORY); - - int nBlocksLeft = spAPEDecompress->GetInfo(APE_DECOMPRESS_TOTAL_BLOCKS); - - // create the progress helper - spMACProgressHelper.Assign(new CMACProgressHelper(nBlocksLeft / BLOCKS_PER_DECODE, pPercentageDone, ProgressCallback, pKillFlag)); - - // main decoding loop - while (nBlocksLeft > 0) - { - // decode data - int nBlocksDecoded = -1; - int nRetVal = spAPEDecompress->GetData((char *) spTempBuffer.GetPtr(), BLOCKS_PER_DECODE, &nBlocksDecoded); - if (nRetVal != ERROR_SUCCESS) - throw(ERROR_INVALID_CHECKSUM); - - // handle the output - if (nOutputMode == UNMAC_DECODER_OUTPUT_WAV) - { - unsigned int nBytesToWrite = (nBlocksDecoded * spAPEDecompress->GetInfo(APE_INFO_BLOCK_ALIGN)); - unsigned int nBytesWritten = 0; - int nRetVal = spioOutput->Write(spTempBuffer, nBytesToWrite, &nBytesWritten); - if ((nRetVal != 0) || (nBytesToWrite != nBytesWritten)) - throw(ERROR_IO_WRITE); - } - else if (nOutputMode == UNMAC_DECODER_OUTPUT_APE) - { - THROW_ON_ERROR(spAPECompress->AddData(spTempBuffer, nBlocksDecoded * spAPEDecompress->GetInfo(APE_INFO_BLOCK_ALIGN))) - } - - // update amount remaining - nBlocksLeft -= nBlocksDecoded; - - // update progress and kill flag - spMACProgressHelper->UpdateProgress(); - if (spMACProgressHelper->ProcessKillFlag(TRUE) != 0) - throw(ERROR_USER_STOPPED_PROCESSING); - } - - // terminate the output - if (nOutputMode == UNMAC_DECODER_OUTPUT_WAV) - { - // write any terminating WAV data - if (spAPEDecompress->GetInfo(APE_INFO_WAV_TERMINATING_BYTES) > 0) - { - spTempBuffer.Assign(new unsigned char[spAPEDecompress->GetInfo(APE_INFO_WAV_TERMINATING_BYTES)], TRUE); - if (spTempBuffer == NULL) throw(ERROR_INSUFFICIENT_MEMORY); - THROW_ON_ERROR(spAPEDecompress->GetInfo(APE_INFO_WAV_TERMINATING_DATA, (int) spTempBuffer.GetPtr(), spAPEDecompress->GetInfo(APE_INFO_WAV_TERMINATING_BYTES))) - - unsigned int nBytesToWrite = spAPEDecompress->GetInfo(APE_INFO_WAV_TERMINATING_BYTES); - unsigned int nBytesWritten = 0; - int nRetVal = spioOutput->Write(spTempBuffer, nBytesToWrite, &nBytesWritten); - if ((nRetVal != 0) || (nBytesToWrite != nBytesWritten)) - throw(ERROR_IO_WRITE); - } - } - else if (nOutputMode == UNMAC_DECODER_OUTPUT_APE) - { - // write the WAV data and any tag -#ifndef NO_TAG - int nTagBytes = GET_TAG(spAPEDecompress)->GetTagBytes(); -#else - int nTagBytes = 0; -#endif - BOOL bHasTag = (nTagBytes > 0); - int nTerminatingBytes = nTagBytes; - nTerminatingBytes += spAPEDecompress->GetInfo(APE_INFO_WAV_TERMINATING_BYTES); - - if (nTerminatingBytes > 0) - { - spTempBuffer.Assign(new unsigned char[nTerminatingBytes], TRUE); - if (spTempBuffer == NULL) throw(ERROR_INSUFFICIENT_MEMORY); - - THROW_ON_ERROR(spAPEDecompress->GetInfo(APE_INFO_WAV_TERMINATING_DATA, (int) spTempBuffer.GetPtr(), nTerminatingBytes)) - - if (bHasTag) - { - unsigned int nBytesRead = 0; - THROW_ON_ERROR(GET_IO(spAPEDecompress)->Seek(-(nTagBytes), FILE_END)) - THROW_ON_ERROR(GET_IO(spAPEDecompress)->Read(&spTempBuffer[spAPEDecompress->GetInfo(APE_INFO_WAV_TERMINATING_BYTES)], nTagBytes, &nBytesRead)) - } - - THROW_ON_ERROR(spAPECompress->Finish(spTempBuffer, nTerminatingBytes, spAPEDecompress->GetInfo(APE_INFO_WAV_TERMINATING_BYTES))); - } - else - { - THROW_ON_ERROR(spAPECompress->Finish(NULL, 0, 0)); - } - } - - // fire the "complete" progress notification - spMACProgressHelper->UpdateProgressComplete(); - } - catch(int nErrorCode) - { - nFunctionRetVal = (nErrorCode == 0) ? ERROR_UNDEFINED : nErrorCode; - } - catch(...) - { - nFunctionRetVal = ERROR_UNDEFINED; - } - - // return - return nFunctionRetVal; -} diff --git a/MAC_SDK/Source/MACLib/APETag.cpp b/MAC_SDK/Source/MACLib/APETag.cpp deleted file mode 100644 index d2582b9..0000000 --- a/MAC_SDK/Source/MACLib/APETag.cpp +++ /dev/null @@ -1,745 +0,0 @@ -#include "All.h" -#include "ID3Genres.h" -#ifndef NO_TAG -#include "APETag.h" -#endif -#include "CharacterHelper.h" -#include "IO.h" -#include IO_HEADER_FILE - -/***************************************************************************************** -CAPETagField -*****************************************************************************************/ - -CAPETagField::CAPETagField(const str_utf16 * pFieldName, const void * pFieldValue, int nFieldBytes, int nFlags) -{ - // field name - m_spFieldNameUTF16.Assign(new str_utf16 [wcslen(pFieldName) + 1], TRUE); - memcpy(m_spFieldNameUTF16, pFieldName, (wcslen(pFieldName) + 1) * sizeof(str_utf16)); - - // data (we'll always allocate two extra bytes and memset to 0 so we're safely NULL terminated) - m_nFieldValueBytes = max(nFieldBytes, 0); - m_spFieldValue.Assign(new char [m_nFieldValueBytes + 2], TRUE); - memset(m_spFieldValue, 0, m_nFieldValueBytes + 2); - if (m_nFieldValueBytes > 0) - memcpy(m_spFieldValue, pFieldValue, m_nFieldValueBytes); - - // flags - m_nFieldFlags = nFlags; -} - -CAPETagField::~CAPETagField() -{ -} - -int CAPETagField::GetFieldSize() -{ - CSmartPtr spFieldNameANSI(GetANSIFromUTF16(m_spFieldNameUTF16), TRUE); - return (strlen(spFieldNameANSI) + 1) + m_nFieldValueBytes + 4 + 4; -} - -const str_utf16 * CAPETagField::GetFieldName() -{ - return m_spFieldNameUTF16; -} - -const char * CAPETagField::GetFieldValue() -{ - return m_spFieldValue; -} - -int CAPETagField::GetFieldValueSize() -{ - return m_nFieldValueBytes; -} - -int CAPETagField::GetFieldFlags() -{ - return m_nFieldFlags; -} - -int CAPETagField::SaveField(char * pBuffer) -{ - *((int *) pBuffer) = m_nFieldValueBytes; - pBuffer += 4; - *((int *) pBuffer) = m_nFieldFlags; - pBuffer += 4; - - CSmartPtr spFieldNameANSI((char *) GetANSIFromUTF16(m_spFieldNameUTF16), TRUE); - strcpy(pBuffer, spFieldNameANSI); - pBuffer += strlen(spFieldNameANSI) + 1; - - memcpy(pBuffer, m_spFieldValue, m_nFieldValueBytes); - - return GetFieldSize(); -} - - -/***************************************************************************************** -CAPETag -*****************************************************************************************/ - -CAPETag::CAPETag(const str_utf16 * pFilename, BOOL bAnalyze) -{ - m_spIO.Assign(new IO_CLASS_NAME); - m_spIO->Open(pFilename); - - m_bAnalyzed = FALSE; - m_nFields = 0; - m_nTagBytes = 0; - m_bIgnoreReadOnly = FALSE; - - if (bAnalyze) - { - Analyze(); - } -} - -CAPETag::CAPETag(CIO * pIO, BOOL bAnalyze) -{ - m_spIO.Assign(pIO, FALSE, FALSE); // we don't own the IO source - m_bAnalyzed = FALSE; - m_nFields = 0; - m_nTagBytes = 0; - - if (bAnalyze) - { - Analyze(); - } -} - -CAPETag::~CAPETag() -{ - ClearFields(); -} - -int CAPETag::GetTagBytes() -{ - if (m_bAnalyzed == FALSE) { Analyze(); } - - return m_nTagBytes; -} - -CAPETagField * CAPETag::GetTagField(int nIndex) -{ - if (m_bAnalyzed == FALSE) { Analyze(); } - - if ((nIndex >= 0) && (nIndex < m_nFields)) - { - return m_aryFields[nIndex]; - } - - return NULL; -} - -int CAPETag::Save(BOOL bUseOldID3) -{ - if (Remove(FALSE) != ERROR_SUCCESS) - return -1; - - if (m_nFields == 0) { return ERROR_SUCCESS; } - - int nRetVal = -1; - - if (bUseOldID3 == FALSE) - { - int z = 0; - - // calculate the size of the whole tag - int nFieldBytes = 0; - for (z = 0; z < m_nFields; z++) - nFieldBytes += m_aryFields[z]->GetFieldSize(); - - // sort the fields - SortFields(); - - // build the footer - APE_TAG_FOOTER APETagFooter(m_nFields, nFieldBytes); - - // make a buffer for the tag - int nTotalTagBytes = APETagFooter.GetTotalTagBytes(); - CSmartPtr spRawTag(new char [nTotalTagBytes], TRUE); - - // save the fields - int nLocation = 0; - for (z = 0; z < m_nFields; z++) - nLocation += m_aryFields[z]->SaveField(&spRawTag[nLocation]); - - // add the footer to the buffer - memcpy(&spRawTag[nLocation], &APETagFooter, APE_TAG_FOOTER_BYTES); - nLocation += APE_TAG_FOOTER_BYTES; - - // dump the tag to the I/O source - nRetVal = WriteBufferToEndOfIO(spRawTag, nTotalTagBytes); - } - else - { - // build the ID3 tag - ID3_TAG ID3Tag; - CreateID3Tag(&ID3Tag); - nRetVal = WriteBufferToEndOfIO(&ID3Tag, sizeof(ID3_TAG)); - } - - return nRetVal; -} - -int CAPETag::WriteBufferToEndOfIO(void * pBuffer, int nBytes) -{ - int nOriginalPosition = m_spIO->GetPosition(); - - unsigned int nBytesWritten = 0; - m_spIO->Seek(0, FILE_END); - - int nRetVal = m_spIO->Write(pBuffer, nBytes, &nBytesWritten); - - m_spIO->Seek(nOriginalPosition, FILE_BEGIN); - - return nRetVal; -} - -int CAPETag::Analyze() -{ - // clean-up - ID3_TAG ID3Tag; - ClearFields(); - m_nTagBytes = 0; - - m_bAnalyzed = TRUE; - - // store the original location - int nOriginalPosition = m_spIO->GetPosition(); - - // check for a tag - unsigned int nBytesRead; - int nRetVal; - m_bHasID3Tag = FALSE; - m_bHasAPETag = FALSE; - m_nAPETagVersion = -1; - m_spIO->Seek(-ID3_TAG_BYTES, FILE_END); - nRetVal = m_spIO->Read((unsigned char *) &ID3Tag, sizeof(ID3_TAG), &nBytesRead); - - if ((nBytesRead == sizeof(ID3_TAG)) && (nRetVal == 0)) - { - if (ID3Tag.Header[0] == 'T' && ID3Tag.Header[1] == 'A' && ID3Tag.Header[2] == 'G') - { - m_bHasID3Tag = TRUE; - m_nTagBytes += ID3_TAG_BYTES; - } - } - - // set the fields - if (m_bHasID3Tag) - { - SetFieldID3String(APE_TAG_FIELD_ARTIST, ID3Tag.Artist, 30); - SetFieldID3String(APE_TAG_FIELD_ALBUM, ID3Tag.Album, 30); - SetFieldID3String(APE_TAG_FIELD_TITLE, ID3Tag.Title, 30); - SetFieldID3String(APE_TAG_FIELD_COMMENT, ID3Tag.Comment, 28); - SetFieldID3String(APE_TAG_FIELD_YEAR, ID3Tag.Year, 4); - - char cTemp[16]; sprintf(cTemp, "%d", ID3Tag.Track); - SetFieldString(APE_TAG_FIELD_TRACK, cTemp, FALSE); - - if ((ID3Tag.Genre == GENRE_UNDEFINED) || (ID3Tag.Genre >= GENRE_COUNT)) - SetFieldString(APE_TAG_FIELD_GENRE, APE_TAG_GENRE_UNDEFINED); - else - SetFieldString(APE_TAG_FIELD_GENRE, g_ID3Genre[ID3Tag.Genre]); - } - - // try loading the APE tag - if (m_bHasID3Tag == FALSE) - { - APE_TAG_FOOTER APETagFooter; - m_spIO->Seek(-int(APE_TAG_FOOTER_BYTES), FILE_END); - nRetVal = m_spIO->Read((unsigned char *) &APETagFooter, APE_TAG_FOOTER_BYTES, &nBytesRead); - if ((nBytesRead == APE_TAG_FOOTER_BYTES) && (nRetVal == 0)) - { - if (APETagFooter.GetIsValid(FALSE)) - { - m_bHasAPETag = TRUE; - m_nAPETagVersion = APETagFooter.GetVersion(); - - int nRawFieldBytes = APETagFooter.GetFieldBytes(); - m_nTagBytes += APETagFooter.GetTotalTagBytes(); - - CSmartPtr spRawTag(new char [nRawFieldBytes], TRUE); - m_spIO->Seek(-(APETagFooter.GetTotalTagBytes() - APETagFooter.GetFieldsOffset()), FILE_END); - nRetVal = m_spIO->Read((unsigned char *) spRawTag.GetPtr(), nRawFieldBytes, &nBytesRead); - - if ((nRetVal == 0) && (nRawFieldBytes == int(nBytesRead))) - { - // parse out the raw fields - int nLocation = 0; - for (int z = 0; z < APETagFooter.GetNumberFields(); z++) - { - int nMaximumFieldBytes = nRawFieldBytes - nLocation; - - int nBytes = 0; - if (LoadField(&spRawTag[nLocation], nMaximumFieldBytes, &nBytes) != ERROR_SUCCESS) - { - // if LoadField(...) fails, it means that the tag is corrupt (accidently or intentionally) - // we'll just bail out -- leaving the fields we've already set - break; - } - nLocation += nBytes; - } - } - } - } - } - - // restore the file pointer - m_spIO->Seek(nOriginalPosition, FILE_BEGIN); - - return ERROR_SUCCESS; -} - -int CAPETag::ClearFields() -{ - for (int z = 0; z < m_nFields; z++) - { - SAFE_DELETE(m_aryFields[z]) - } - - m_nFields = 0; - - return ERROR_SUCCESS; -} - -int CAPETag::GetTagFieldIndex(const str_utf16 * pFieldName) -{ - if (m_bAnalyzed == FALSE) { Analyze(); } - if (pFieldName == NULL) return -1; - - for (int z = 0; z < m_nFields; z++) - { - if (wcsicmp(m_aryFields[z]->GetFieldName(), pFieldName) == 0) - return z; - } - - return -1; - -} - -CAPETagField * CAPETag::GetTagField(const str_utf16 * pFieldName) -{ - int nIndex = GetTagFieldIndex(pFieldName); - return (nIndex != -1) ? m_aryFields[nIndex] : NULL; -} - -int CAPETag::GetFieldString(const str_utf16 * pFieldName, str_ansi * pBuffer, int * pBufferCharacters, BOOL bUTF8Encode) -{ - int nOriginalCharacters = *pBufferCharacters; - str_utf16 * pUTF16 = new str_utf16 [*pBufferCharacters + 1]; - pUTF16[0] = 0; - - int nRetVal = GetFieldString(pFieldName, pUTF16, pBufferCharacters); - if (nRetVal == ERROR_SUCCESS) - { - CSmartPtr spANSI(bUTF8Encode ? (str_ansi *) GetUTF8FromUTF16(pUTF16) : GetANSIFromUTF16(pUTF16), TRUE); - if (int(strlen(spANSI)) > nOriginalCharacters) - { - memset(pBuffer, 0, nOriginalCharacters * sizeof(str_ansi)); - *pBufferCharacters = 0; - nRetVal = ERROR_UNDEFINED; - } - else - { - strcpy(pBuffer, spANSI); - *pBufferCharacters = strlen(spANSI); - } - } - - delete [] pUTF16; - - return nRetVal; -} - - -int CAPETag::GetFieldString(const str_utf16 * pFieldName, str_utf16 * pBuffer, int * pBufferCharacters) -{ - if (m_bAnalyzed == FALSE) { Analyze(); } - - int nRetVal = ERROR_UNDEFINED; - - if (*pBufferCharacters > 0) - { - CAPETagField * pAPETagField = GetTagField(pFieldName); - if (pAPETagField == NULL) - { - // the field doesn't exist -- return an empty string - memset(pBuffer, 0, *pBufferCharacters * sizeof(str_utf16)); - *pBufferCharacters = 0; - } - else if (pAPETagField->GetIsUTF8Text() || (m_nAPETagVersion < 2000)) - { - // get the value in UTF-16 format - CSmartPtr spUTF16; - if (m_nAPETagVersion >= 2000) - spUTF16.Assign(GetUTF16FromUTF8((str_utf8 *) pAPETagField->GetFieldValue()), TRUE); - else - spUTF16.Assign(GetUTF16FromANSI(pAPETagField->GetFieldValue()), TRUE); - - // get the number of characters - int nCharacters = (wcslen(spUTF16) + 1); - if (nCharacters > *pBufferCharacters) - { - // we'll fail here, because it's not clear what would get returned (null termination, size, etc.) - // and we really don't want to cause buffer overruns on the client side - *pBufferCharacters = nCharacters; - } - else - { - // just copy in - *pBufferCharacters = nCharacters; - memcpy(pBuffer, spUTF16.GetPtr(), *pBufferCharacters * sizeof(str_utf16)); - nRetVal = ERROR_SUCCESS; - } - } - else - { - // memset the whole buffer to NULL (so everything left over is NULL terminated) - memset(pBuffer, 0, *pBufferCharacters * sizeof(str_utf16)); - - // do a binary dump (need to convert from wchar's to bytes) - int nBufferBytes = (*pBufferCharacters - 1) * sizeof(str_utf16); - nRetVal = GetFieldBinary(pFieldName, pBuffer, &nBufferBytes); - *pBufferCharacters = (nBufferBytes / sizeof(str_utf16)) + 1; - } - } - - return nRetVal; -} - -int CAPETag::GetFieldBinary(const str_utf16 * pFieldName, void * pBuffer, int * pBufferBytes) -{ - if (m_bAnalyzed == FALSE) { Analyze(); } - - int nRetVal = ERROR_UNDEFINED; - - if (*pBufferBytes > 0) - { - CAPETagField * pAPETagField = GetTagField(pFieldName); - if (pAPETagField == NULL) - { - memset(pBuffer, 0, *pBufferBytes); - *pBufferBytes = 0; - } - else - { - if (pAPETagField->GetFieldValueSize() > *pBufferBytes) - { - // we'll fail here, because partial data may be worse than no data - memset(pBuffer, 0, *pBufferBytes); - *pBufferBytes = pAPETagField->GetFieldValueSize(); - } - else - { - // memcpy - *pBufferBytes = pAPETagField->GetFieldValueSize(); - memcpy(pBuffer, pAPETagField->GetFieldValue(), *pBufferBytes); - nRetVal = ERROR_SUCCESS; - } - } - } - - return nRetVal; -} - -int CAPETag::CreateID3Tag(ID3_TAG * pID3Tag) -{ - // error check - if (pID3Tag == NULL) { return -1; } - if (m_bAnalyzed == FALSE) { Analyze(); } - if (m_nFields == 0) { return -1; } - - // empty - ZeroMemory(pID3Tag, ID3_TAG_BYTES); - - // header - pID3Tag->Header[0] = 'T'; pID3Tag->Header[1] = 'A'; pID3Tag->Header[2] = 'G'; - - // standard fields - GetFieldID3String(APE_TAG_FIELD_ARTIST, pID3Tag->Artist, 30); - GetFieldID3String(APE_TAG_FIELD_ALBUM, pID3Tag->Album, 30); - GetFieldID3String(APE_TAG_FIELD_TITLE, pID3Tag->Title, 30); - GetFieldID3String(APE_TAG_FIELD_COMMENT, pID3Tag->Comment, 28); - GetFieldID3String(APE_TAG_FIELD_YEAR, pID3Tag->Year, 4); - - // track number - str_utf16 cBuffer[256] = { 0 }; int nBufferCharacters = 255; - GetFieldString(APE_TAG_FIELD_TRACK, cBuffer, &nBufferCharacters); - pID3Tag->Track = (unsigned char) _wtoi(cBuffer); - - // genre - cBuffer[0] = 0; nBufferCharacters = 255; - GetFieldString(APE_TAG_FIELD_GENRE, cBuffer, &nBufferCharacters); - - // convert the genre string to an index - pID3Tag->Genre = 255; - int nGenreIndex = 0; - BOOL bFound = FALSE; - while ((nGenreIndex < GENRE_COUNT) && (bFound == FALSE)) - { - if (_wcsicmp(cBuffer, g_ID3Genre[nGenreIndex]) == 0) - { - pID3Tag->Genre = nGenreIndex; - bFound = TRUE; - } - - nGenreIndex++; - } - - return ERROR_SUCCESS; -} - -int CAPETag::LoadField(const char * pBuffer, int nMaximumBytes, int * pBytes) -{ - // set bytes to 0 - if (pBytes) *pBytes = 0; - - // size and flags - int nLocation = 0; - int nFieldValueSize = *((int *) &pBuffer[nLocation]); - nLocation += 4; - int nFieldFlags = *((int *) &pBuffer[nLocation]); - nLocation += 4; - - // safety check (so we can't get buffer overflow attacked) - int nMaximumRead = nMaximumBytes - 8 - nFieldValueSize; - BOOL bSafe = TRUE; - for (int z = 0; (z < nMaximumRead) && (bSafe == TRUE); z++) - { - int nCharacter = pBuffer[nLocation + z]; - if (nCharacter == 0) - break; - if ((nCharacter < 0x20) || (nCharacter > 0x7E)) - bSafe = FALSE; - } - if (bSafe == FALSE) - return -1; - - // name - int nNameCharacters = strlen(&pBuffer[nLocation]); - CSmartPtr spNameUTF8(new str_utf8 [nNameCharacters + 1], TRUE); - memcpy(spNameUTF8, &pBuffer[nLocation], (nNameCharacters + 1) * sizeof(str_utf8)); - nLocation += nNameCharacters + 1; - CSmartPtr spNameUTF16(GetUTF16FromUTF8(spNameUTF8.GetPtr()), TRUE); - - // value - CSmartPtr spFieldBuffer(new char [nFieldValueSize], TRUE); - memcpy(spFieldBuffer, &pBuffer[nLocation], nFieldValueSize); - nLocation += nFieldValueSize; - - // update the bytes - if (pBytes) *pBytes = nLocation; - - // set - return SetFieldBinary(spNameUTF16.GetPtr(), spFieldBuffer, nFieldValueSize, nFieldFlags); -} - -int CAPETag::SetFieldString(const str_utf16 * pFieldName, const str_utf16 * pFieldValue) -{ - // remove if empty - if ((pFieldValue == NULL) || (wcslen(pFieldValue) <= 0)) - return RemoveField(pFieldName); - - // UTF-8 encode the value and call the UTF-8 SetField(...) - CSmartPtr spFieldValueUTF8(GetUTF8FromUTF16((str_utf16 *) pFieldValue), TRUE); - return SetFieldString(pFieldName, (const char *) spFieldValueUTF8.GetPtr(), TRUE); -} - -int CAPETag::SetFieldString(const str_utf16 * pFieldName, const char * pFieldValue, BOOL bAlreadyUTF8Encoded) -{ - // remove if empty - if ((pFieldValue == NULL) || (strlen(pFieldValue) <= 0)) - return RemoveField(pFieldName); - - // get the length and call the binary SetField(...) - if (bAlreadyUTF8Encoded == FALSE) - { - CSmartPtr spUTF8((char *) GetUTF8FromANSI(pFieldValue), TRUE); - int nFieldBytes = strlen(spUTF8.GetPtr()); - return SetFieldBinary(pFieldName, spUTF8.GetPtr(), nFieldBytes, TAG_FIELD_FLAG_DATA_TYPE_TEXT_UTF8); - } - else - { - int nFieldBytes = strlen(pFieldValue); - return SetFieldBinary(pFieldName, pFieldValue, nFieldBytes, TAG_FIELD_FLAG_DATA_TYPE_TEXT_UTF8); - } -} - -int CAPETag::SetFieldBinary(const str_utf16 * pFieldName, const void * pFieldValue, int nFieldBytes, int nFieldFlags) -{ - if (m_bAnalyzed == FALSE) { Analyze(); } - if (pFieldName == NULL) return -1; - - // check to see if we're trying to remove the field (by setting it to NULL or an empty string) - BOOL bRemoving = (pFieldValue == NULL) || (nFieldBytes <= 0); - - // get the index - int nFieldIndex = GetTagFieldIndex(pFieldName); - if (nFieldIndex != -1) - { - // existing field - - // fail if we're read-only (and not ignoring the read-only flag) - if ((m_bIgnoreReadOnly == FALSE) && (m_aryFields[nFieldIndex]->GetIsReadOnly())) - return -1; - - // erase the existing field - SAFE_DELETE(m_aryFields[nFieldIndex]) - - if (bRemoving) - { - return RemoveField(nFieldIndex); - } - } - else - { - if (bRemoving) - return ERROR_SUCCESS; - - nFieldIndex = m_nFields; - m_nFields++; - } - - // create the field and add it to the field array - m_aryFields[nFieldIndex] = new CAPETagField(pFieldName, pFieldValue, nFieldBytes, nFieldFlags); - - return ERROR_SUCCESS; -} - -int CAPETag::RemoveField(int nIndex) -{ - if ((nIndex >= 0) && (nIndex < m_nFields)) - { - SAFE_DELETE(m_aryFields[nIndex]) - memmove(&m_aryFields[nIndex], &m_aryFields[nIndex + 1], (256 - nIndex - 1) * sizeof(CAPETagField *)); - m_nFields--; - return ERROR_SUCCESS; - } - - return -1; -} - -int CAPETag::RemoveField(const str_utf16 * pFieldName) -{ - return RemoveField(GetTagFieldIndex(pFieldName)); -} - -int CAPETag::Remove(BOOL bUpdate) -{ - // variables - unsigned int nBytesRead = 0; - int nRetVal = 0; - int nOriginalPosition = m_spIO->GetPosition(); - - BOOL bID3Removed = TRUE; - BOOL bAPETagRemoved = TRUE; - - BOOL bFailedToRemove = FALSE; - - while (bID3Removed || bAPETagRemoved) - { - bID3Removed = FALSE; - bAPETagRemoved = FALSE; - - // ID3 tag - if (m_spIO->GetSize() > ID3_TAG_BYTES) - { - char cTagHeader[3]; - m_spIO->Seek(-ID3_TAG_BYTES, FILE_END); - nRetVal = m_spIO->Read(cTagHeader, 3, &nBytesRead); - if ((nRetVal == 0) && (nBytesRead == 3)) - { - if (strncmp(cTagHeader, "TAG", 3) == 0) - { - m_spIO->Seek(-ID3_TAG_BYTES, FILE_END); - if (m_spIO->SetEOF() != 0) - bFailedToRemove = TRUE; - else - bID3Removed = TRUE; - } - } - } - - - // APE Tag - if (m_spIO->GetSize() > APE_TAG_FOOTER_BYTES && bFailedToRemove == FALSE) - { - APE_TAG_FOOTER APETagFooter; - m_spIO->Seek(-int(APE_TAG_FOOTER_BYTES), FILE_END); - nRetVal = m_spIO->Read(&APETagFooter, APE_TAG_FOOTER_BYTES, &nBytesRead); - if ((nRetVal == 0) && (nBytesRead == APE_TAG_FOOTER_BYTES)) - { - if (APETagFooter.GetIsValid(TRUE)) - { - m_spIO->Seek(-APETagFooter.GetTotalTagBytes(), FILE_END); - - if (m_spIO->SetEOF() != 0) - bFailedToRemove = TRUE; - else - bAPETagRemoved = TRUE; - } - } - } - - } - - m_spIO->Seek(nOriginalPosition, FILE_BEGIN); - - if (bUpdate && bFailedToRemove == FALSE) - { - Analyze(); - } - - return bFailedToRemove ? -1 : 0; -} - -int CAPETag::SetFieldID3String(const str_utf16 * pFieldName, const char * pFieldValue, int nBytes) -{ - // allocate a buffer and terminate it - CSmartPtr spBuffer(new str_ansi [nBytes + 1], TRUE); - spBuffer[nBytes] = 0; - - // make a capped copy of the string - memcpy(spBuffer.GetPtr(), pFieldValue, nBytes); - - // remove trailing white-space - char * pEnd = &spBuffer[nBytes]; - while (((*pEnd == ' ') || (*pEnd == 0)) && pEnd >= &spBuffer[0]) { *pEnd-- = 0; } - - // set the field - SetFieldString(pFieldName, spBuffer, FALSE); - - return ERROR_SUCCESS; -} - -int CAPETag::GetFieldID3String(const str_utf16 * pFieldName, char * pBuffer, int nBytes) -{ - int nBufferCharacters = 255; str_utf16 cBuffer[256] = {0}; - GetFieldString(pFieldName, cBuffer, &nBufferCharacters); - - CSmartPtr spBufferANSI(GetANSIFromUTF16(cBuffer), TRUE); - - memset(pBuffer, 0, nBytes); - strncpy(pBuffer, spBufferANSI.GetPtr(), nBytes); - - return ERROR_SUCCESS; -} - -int CAPETag::SortFields() -{ - // sort the tag fields by size (so that the smallest fields are at the front of the tag) - qsort(m_aryFields, m_nFields, sizeof(CAPETagField *), CompareFields); - - return ERROR_SUCCESS; -} - -int CAPETag::CompareFields(const void * pA, const void * pB) -{ - CAPETagField * pFieldA = *((CAPETagField **) pA); - CAPETagField * pFieldB = *((CAPETagField **) pB); - - return (pFieldA->GetFieldSize() - pFieldB->GetFieldSize()); -} \ No newline at end of file diff --git a/MAC_SDK/Source/MACLib/APETag.h b/MAC_SDK/Source/MACLib/APETag.h deleted file mode 100644 index eecd8b7..0000000 --- a/MAC_SDK/Source/MACLib/APETag.h +++ /dev/null @@ -1,293 +0,0 @@ -#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 m_spFieldNameUTF16; - CSmartPtr 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 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 - diff --git a/MAC_SDK/Source/MACLib/Assembly/Assembly.h b/MAC_SDK/Source/MACLib/Assembly/Assembly.h deleted file mode 100644 index 6bb1c91..0000000 --- a/MAC_SDK/Source/MACLib/Assembly/Assembly.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef APE_ASSEMBLY_H -#define APE_ASSEMBLY_H - -extern "C" -{ - void Adapt(short * pM, const short * pAdapt, int nDirection, int nOrder); - int CalculateDotProduct(const short * pA, const short * pB, int nOrder); - BOOL GetMMXAvailable(); -}; - -#endif // #ifndef APE_ASSEMBLY_H - diff --git a/MAC_SDK/Source/MACLib/Assembly/Assembly.nas b/MAC_SDK/Source/MACLib/Assembly/Assembly.nas deleted file mode 100644 index 70140a5..0000000 --- a/MAC_SDK/Source/MACLib/Assembly/Assembly.nas +++ /dev/null @@ -1,181 +0,0 @@ - -%include "Tools.inc" - -segment_code - -; -; void Adapt ( short* pM, const short* pAdapt, int nDirection, int nOrder ) -; -; [esp+16] nOrder -; [esp+12] nDirection -; [esp+ 8] pAdapt -; [esp+ 4] pM -; [esp+ 0] Return Address - - align 16 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop -proc Adapt - - mov eax, [esp + 4] ; pM - mov ecx, [esp + 8] ; pAdapt - mov edx, [esp + 16] ; nOrder - shr edx, 4 - - cmp dword [esp + 12], byte 0 ; nDirection - jle short AdaptSub - -AdaptAddLoop: - movq mm0, [eax] - paddw mm0, [ecx] - movq [eax], mm0 - movq mm1, [eax + 8] - paddw mm1, [ecx + 8] - movq [eax + 8], mm1 - movq mm2, [eax + 16] - paddw mm2, [ecx + 16] - movq [eax + 16], mm2 - movq mm3, [eax + 24] - paddw mm3, [ecx + 24] - movq [eax + 24], mm3 - add eax, byte 32 - add ecx, byte 32 - dec edx - jnz AdaptAddLoop - - emms - ret - - align 16 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - -AdaptSub: je short AdaptDone - -AdaptSubLoop: - movq mm0, [eax] - psubw mm0, [ecx] - movq [eax], mm0 - movq mm1, [eax + 8] - psubw mm1, [ecx + 8] - movq [eax + 8], mm1 - movq mm2, [eax + 16] - psubw mm2, [ecx + 16] - movq [eax + 16], mm2 - movq mm3, [eax + 24] - psubw mm3, [ecx + 24] - movq [eax + 24], mm3 - add eax, byte 32 - add ecx, byte 32 - dec edx - jnz AdaptSubLoop - - emms -AdaptDone: - -endproc - -; -; int CalculateDotProduct ( const short* pA, const short* pB, int nOrder ) -; -; [esp+12] nOrder -; [esp+ 8] pB -; [esp+ 4] pA -; [esp+ 0] Return Address - - align 16 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - -proc CalculateDotProduct - - mov eax, [esp + 4] ; pA - mov ecx, [esp + 8] ; pB - mov edx, [esp + 12] ; nOrder - shr edx, 4 - pxor mm7, mm7 - -loopDot: movq mm0, [eax] - pmaddwd mm0, [ecx] - paddd mm7, mm0 - movq mm1, [eax + 8] - pmaddwd mm1, [ecx + 8] - paddd mm7, mm1 - movq mm2, [eax + 16] - pmaddwd mm2, [ecx + 16] - paddd mm7, mm2 - movq mm3, [eax + 24] - pmaddwd mm3, [ecx + 24] - add eax, byte 32 - add ecx, byte 32 - paddd mm7, mm3 - dec edx - jnz loopDot - - movq mm6, mm7 - psrlq mm7, 32 - paddd mm6, mm7 - movd [esp + 4], mm6 - emms - mov eax, [esp + 4] -endproc - - -; -; BOOL GetMMXAvailable ( void ); -; - -proc GetMMXAvailable - pushad - pushfd - pop eax - mov ecx, eax - xor eax, 0x200000 - push eax - popfd - pushfd - pop eax - cmp eax, ecx - jz short return ; no CPUID command, so no MMX - - mov eax,1 - CPUID - test edx,0x800000 -return: popad - setnz al - and eax, byte 1 -endproc - -; end diff --git a/MAC_SDK/Source/MACLib/Assembly/Assembly.obj b/MAC_SDK/Source/MACLib/Assembly/Assembly.obj deleted file mode 100644 index 90b8d6d6a4115671d231bf7fdebc3a6420cb1d87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 818 zcmeZaWMnwMdTCS*BLjmF0|e-mq*jzbm|)U@k%7U6fq?;}1}wn9z@Wg8kT3xbx?NOQ zx_wkQx-e ze}04n|KCUn{`v@s<^u}N2Nk?ZPw|%@hMSAbD6s&U_Y-d3PbBkxBANG-Nb``~%yaM+ z3;+B7AoIU6^8fn*cJEhD4*q{X!Or~}D8T>k7udC5BcU$k|M%Og^elh=cmCq*3jF`R z^VgNAu<)0IOg)@1C!+J9DJYNv=FW+*JW;~CgOP!Ofq&8WLktWJ42k?x4>UhuJgk?N znUe|)(0~6K7}6OXi;GiplX5Ec@)C<763B4@GJ}~B6dMpZ7^#<-RGgnv3XZb>{}~vV z8R8vN5(`Qg7`PZ17(lw17@z`3A|Tx?;FyG{VTPy)E=|gV>S6{dVGv|sU?@Nlkz-(B zSb-v|YVsan@1A`fi(VqKR@w* z2vkVp{~Dx_#{civC;ktS25J0Xqu>FR#{ciPfq{R~_k&=1>Vf75j8T!%hxO7jb5fzn;@^J;hIB^9 z;^NfYq?}4K6TQ5|VvrPaiUR3oW(1`vkPHIrB_23@EcW{?1bI0FMiGm3~F0|Ubv6cHB&28Qh@B7O`E3};b9 z5*Zj6lo=tmLrkti~7#J8f zz(rj0OWZQ^5_2xVML-7KWME);0~LXo{0c?n7Xt$%j2u%^eDd=PLJJa8Qp!<6r67q0mnIpaYAYx%O~PgprZC7Pgs4k?UaBEOymMksa%oOtNvcbJNkCD4N@;Ql s12!>`t6lO-T+34P7+ms8{POd_%y{?I5?|j4$FjuCoW!J@R0ecD03CyAt^fc4 diff --git a/MAC_SDK/Source/MACLib/Assembly/Tools.inc b/MAC_SDK/Source/MACLib/Assembly/Tools.inc deleted file mode 100644 index e1f79d9..0000000 --- a/MAC_SDK/Source/MACLib/Assembly/Tools.inc +++ /dev/null @@ -1,117 +0,0 @@ -; -; (C) Ururi 1999 -; - -BITS 32 - -%ifdef WIN32 - %define _NAMING - %define segment_code segment .text align=32 class=CODE use32 - %define segment_data segment .data align=32 class=DATA use32 - %ifdef __BORLANDC__ - %define segment_bss segment .data align=32 class=DATA use32 - %else - %define segment_bss segment .bss align=32 class=DATA use32 - %endif - -%elifdef AOUT - %define _NAMING - %define segment_code segment .text - %define segment_data segment .data - %define segment_bss segment .bss - -%else - %define segment_code segment .text align=32 class=CODE use32 - %define segment_data segment .data align=32 class=DATA use32 - %define segment_bss segment .bss align=32 class=DATA use32 -%endif - -%define pmov movq -%define pmovd movd - -%define pupldq punpckldq -%define puphdq punpckhdq -%define puplwd punpcklwd -%define puphwd punpckhwd - -%imacro globaldef 1 - %ifdef _NAMING - %define %1 _%1 - %endif - global %1 -%endmacro - -%imacro externdef 1 - %ifdef _NAMING - %define %1 _%1 - %endif - extern %1 -%endmacro - -%imacro proc 1 - %push proc - global _%1 - global %1 -_%1: -%1: - %assign %$STACK 0 - %assign %$STACKN 0 - %assign %$ARG 4 -%endmacro - -%imacro endproc 0 - %ifnctx proc - %error expected 'proc' before 'endproc'. - %else - %if %$STACK > 0 - add esp, %$STACK - %endif - - %if %$STACK <> (-%$STACKN) - %error STACKLEVEL mismatch check 'local', 'alloc', 'pushd', 'popd' - %endif - - ret - %pop - %endif -%endmacro - -%idefine sp(a) esp+%$STACK+a - -%imacro arg 1 - %00 equ %$ARG - %assign %$ARG %$ARG+%1 -%endmacro - -%imacro local 1 - %assign %$STACKN %$STACKN-%1 - %00 equ %$STACKN -%endmacro - -%imacro alloc 0 - sub esp, (-%$STACKN)-%$STACK - %assign %$STACK (-%$STACKN) -%endmacro - -%imacro pushd 1-* - %rep %0 - push %1 - %assign %$STACK %$STACK+4 - %rotate 1 - %endrep -%endmacro - -%imacro popd 1-* - %rep %0 - %rotate -1 - pop %1 - %assign %$STACK %$STACK-4 - %endrep -%endmacro - -%macro algn 1 - align 16 - %rep (65536-%1) & 15 - nop - %endrep -%endm diff --git a/MAC_SDK/Source/MACLib/Assembly/Tools64.inc b/MAC_SDK/Source/MACLib/Assembly/Tools64.inc deleted file mode 100644 index 4fbdf69..0000000 --- a/MAC_SDK/Source/MACLib/Assembly/Tools64.inc +++ /dev/null @@ -1,119 +0,0 @@ -; -; (C) Ururi 1999 -; - -BITS 64 - -CPU X64 - -%ifdef WIN32 - %define _NAMING - %define segment_code segment .text align=32 class=CODE use32 - %define segment_data segment .data align=32 class=DATA use32 - %ifdef __BORLANDC__ - %define segment_bss segment .data align=32 class=DATA use32 - %else - %define segment_bss segment .bss align=32 class=DATA use32 - %endif - -%elifdef AOUT - %define _NAMING - %define segment_code segment .text - %define segment_data segment .data - %define segment_bss segment .bss - -%else - %define segment_code segment .text align=32 class=CODE use32 - %define segment_data segment .data align=32 class=DATA use32 - %define segment_bss segment .bss align=32 class=DATA use32 -%endif - -%define pmov movq -%define pmovd movd - -%define pupldq punpckldq -%define puphdq punpckhdq -%define puplwd punpcklwd -%define puphwd punpckhwd - -%imacro globaldef 1 - %ifdef _NAMING - %define %1 _%1 - %endif - global %1 -%endmacro - -%imacro externdef 1 - %ifdef _NAMING - %define %1 _%1 - %endif - extern %1 -%endmacro - -%imacro proc 1 - %push proc - global _%1 - global %1 -_%1: -%1: - %assign %$STACK 0 - %assign %$STACKN 0 - %assign %$ARG 4 -%endmacro - -%imacro endproc 0 - %ifnctx proc - %error expected 'proc' before 'endproc'. - %else - %if %$STACK > 0 - add esp, %$STACK - %endif - - %if %$STACK <> (-%$STACKN) - %error STACKLEVEL mismatch check 'local', 'alloc', 'pushd', 'popd' - %endif - - ret - %pop - %endif -%endmacro - -%idefine sp(a) esp+%$STACK+a - -%imacro arg 1 - %00 equ %$ARG - %assign %$ARG %$ARG+%1 -%endmacro - -%imacro local 1 - %assign %$STACKN %$STACKN-%1 - %00 equ %$STACKN -%endmacro - -%imacro alloc 0 - sub esp, (-%$STACKN)-%$STACK - %assign %$STACK (-%$STACKN) -%endmacro - -%imacro pushd 1-* - %rep %0 - push %1 - %assign %$STACK %$STACK+4 - %rotate 1 - %endrep -%endmacro - -%imacro popd 1-* - %rep %0 - %rotate -1 - pop %1 - %assign %$STACK %$STACK-4 - %endrep -%endmacro - -%macro algn 1 - align 16 - %rep (65536-%1) & 15 - nop - %endrep -%endm diff --git a/MAC_SDK/Source/MACLib/BitArray.cpp b/MAC_SDK/Source/MACLib/BitArray.cpp deleted file mode 100644 index 660257a..0000000 --- a/MAC_SDK/Source/MACLib/BitArray.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/************************************************************************************ -Includes -************************************************************************************/ -#include "All.h" -#include "BitArray.h" -#include "MD5.h" - -/************************************************************************************ -Declares -************************************************************************************/ -#define BIT_ARRAY_ELEMENTS (4096) // the number of elements in the bit array (4 MB) -#define BIT_ARRAY_BYTES (BIT_ARRAY_ELEMENTS * 4) // the number of bytes in the bit array -#define BIT_ARRAY_BITS (BIT_ARRAY_BYTES * 8) // the number of bits in the bit array - -#define MAX_ELEMENT_BITS 128 -#define REFILL_BIT_THRESHOLD (BIT_ARRAY_BITS - MAX_ELEMENT_BITS) - -#define CODE_BITS 32 -#define TOP_VALUE ((unsigned int) 1 << (CODE_BITS - 1)) -#define SHIFT_BITS (CODE_BITS - 9) -#define EXTRA_BITS ((CODE_BITS - 2) % 8 + 1) -#define BOTTOM_VALUE (TOP_VALUE >> 8) - -/************************************************************************************ -Lookup tables -************************************************************************************/ -const uint32 K_SUM_MIN_BOUNDARY[32] = {0,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,0,0,0,0}; - -#define MODEL_ELEMENTS 64 -#define RANGE_OVERFLOW_TOTAL_WIDTH 65536 -#define RANGE_OVERFLOW_SHIFT 16 - -const uint32 RANGE_TOTAL[64] = {0,19578,36160,48417,56323,60899,63265,64435,64971,65232,65351,65416,65447,65466,65476,65482,65485,65488,65490,65491,65492,65493,65494,65495,65496,65497,65498,65499,65500,65501,65502,65503,65504,65505,65506,65507,65508,65509,65510,65511,65512,65513,65514,65515,65516,65517,65518,65519,65520,65521,65522,65523,65524,65525,65526,65527,65528,65529,65530,65531,65532,65533,65534,65535,}; -const uint32 RANGE_WIDTH[64] = {19578,16582,12257,7906,4576,2366,1170,536,261,119,65,31,19,10,6,3,3,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,}; - -#ifdef BUILD_RANGE_TABLE - int g_aryOverflows[256] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - int g_nTotalOverflow = 0; -#endif - -/************************************************************************************ -Constructor -************************************************************************************/ -CBitArray::CBitArray(CIO *pIO) -{ - // allocate memory for the bit array - m_pBitArray = new uint32 [BIT_ARRAY_ELEMENTS]; - memset(m_pBitArray, 0, BIT_ARRAY_BYTES); - - // initialize other variables - m_nCurrentBitIndex = 0; - m_pIO = pIO; -} - -/************************************************************************************ -Destructor -************************************************************************************/ -CBitArray::~CBitArray() -{ - // free the bit array - SAFE_ARRAY_DELETE(m_pBitArray) -#ifdef BUILD_RANGE_TABLE - OutputRangeTable(); -#endif -} - -/************************************************************************************ -Output the bit array via the CIO (typically saves to disk) -************************************************************************************/ -int CBitArray::OutputBitArray(BOOL bFinalize) -{ - // write the entire file to disk - unsigned int nBytesWritten = 0; - unsigned int nBytesToWrite = 0; - unsigned int nRetVal = 0; - - if (bFinalize) - { - nBytesToWrite = ((m_nCurrentBitIndex >> 5) * 4) + 4; - - m_MD5.AddData(m_pBitArray, nBytesToWrite); - - RETURN_ON_ERROR(m_pIO->Write(m_pBitArray, nBytesToWrite, &nBytesWritten)) - - // reset the bit pointer - m_nCurrentBitIndex = 0; - } - else - { - nBytesToWrite = (m_nCurrentBitIndex >> 5) * 4; - - m_MD5.AddData(m_pBitArray, nBytesToWrite); - - RETURN_ON_ERROR(m_pIO->Write(m_pBitArray, nBytesToWrite, &nBytesWritten)) - - // move the last value to the front of the bit array - m_pBitArray[0] = m_pBitArray[m_nCurrentBitIndex >> 5]; - m_nCurrentBitIndex = (m_nCurrentBitIndex & 31); - - // zero the rest of the memory (may not need the +1 because of frame byte alignment) - memset(&m_pBitArray[1], 0, min(nBytesToWrite + 1, BIT_ARRAY_BYTES - 1)); - } - - // return a success - return ERROR_SUCCESS; -} - -/************************************************************************************ -Range coding macros -- ugly, but outperform inline's (every cycle counts here) -************************************************************************************/ -#define PUTC(VALUE) m_pBitArray[m_nCurrentBitIndex >> 5] |= ((VALUE) & 0xFF) << (24 - (m_nCurrentBitIndex & 31)); m_nCurrentBitIndex += 8; -#define PUTC_NOCAP(VALUE) m_pBitArray[m_nCurrentBitIndex >> 5] |= (VALUE) << (24 - (m_nCurrentBitIndex & 31)); m_nCurrentBitIndex += 8; - -#define NORMALIZE_RANGE_CODER \ - while (m_RangeCoderInfo.range <= BOTTOM_VALUE) \ - { \ - if (m_RangeCoderInfo.low < (0xFF << SHIFT_BITS)) \ - { \ - PUTC(m_RangeCoderInfo.buffer); \ - for ( ; m_RangeCoderInfo.help; m_RangeCoderInfo.help--) { PUTC_NOCAP(0xFF); } \ - m_RangeCoderInfo.buffer = (m_RangeCoderInfo.low >> SHIFT_BITS); \ - } \ - else if (m_RangeCoderInfo.low & TOP_VALUE) \ - { \ - PUTC(m_RangeCoderInfo.buffer + 1); \ - m_nCurrentBitIndex += (m_RangeCoderInfo.help * 8); \ - m_RangeCoderInfo.help = 0; \ - m_RangeCoderInfo.buffer = (m_RangeCoderInfo.low >> SHIFT_BITS); \ - } \ - else \ - { \ - m_RangeCoderInfo.help++; \ - } \ - \ - m_RangeCoderInfo.low = (m_RangeCoderInfo.low << 8) & (TOP_VALUE - 1); \ - m_RangeCoderInfo.range <<= 8; \ - } - -#define ENCODE_FAST(RANGE_WIDTH, RANGE_TOTAL, SHIFT) \ - NORMALIZE_RANGE_CODER \ - const int nTemp = m_RangeCoderInfo.range >> (SHIFT); \ - m_RangeCoderInfo.range = nTemp * (RANGE_WIDTH); \ - m_RangeCoderInfo.low += nTemp * (RANGE_TOTAL); - -#define ENCODE_DIRECT(VALUE, SHIFT) \ - NORMALIZE_RANGE_CODER \ - m_RangeCoderInfo.range = m_RangeCoderInfo.range >> (SHIFT); \ - m_RangeCoderInfo.low += m_RangeCoderInfo.range * (VALUE); - -/************************************************************************************ -Directly encode bits to the bitstream -************************************************************************************/ -int CBitArray::EncodeBits(unsigned int nValue, int nBits) -{ - // make sure there is room for the data - // this is a little slower than ensuring a huge block to start with, but it's safer - if (m_nCurrentBitIndex > REFILL_BIT_THRESHOLD) - { - RETURN_ON_ERROR(OutputBitArray()) - } - - ENCODE_DIRECT(nValue, nBits); - return 0; -} - -/************************************************************************************ -Encodes an unsigned int to the bit array (no rice coding) -************************************************************************************/ -int CBitArray::EncodeUnsignedLong(unsigned int n) -{ - // make sure there are at least 8 bytes in the buffer - if (m_nCurrentBitIndex > (BIT_ARRAY_BYTES - 8)) - { - RETURN_ON_ERROR(OutputBitArray()) - } - - // encode the value - uint32 nBitArrayIndex = m_nCurrentBitIndex >> 5; - int nBitIndex = m_nCurrentBitIndex & 31; - - if (nBitIndex == 0) - { - m_pBitArray[nBitArrayIndex] = n; - } - else - { - m_pBitArray[nBitArrayIndex] |= n >> nBitIndex; - m_pBitArray[nBitArrayIndex + 1] = n << (32 - nBitIndex); - } - - m_nCurrentBitIndex += 32; - - return 0; -} - -/************************************************************************************ -Advance to a byte boundary (for frame alignment) -************************************************************************************/ -void CBitArray::AdvanceToByteBoundary() -{ - while (m_nCurrentBitIndex % 8) - m_nCurrentBitIndex++; -} - -/************************************************************************************ -Encode a value -************************************************************************************/ -int CBitArray::EncodeValue(int nEncode, BIT_ARRAY_STATE & BitArrayState) -{ - // make sure there is room for the data - // this is a little slower than ensuring a huge block to start with, but it's safer - if (m_nCurrentBitIndex > REFILL_BIT_THRESHOLD) - { - RETURN_ON_ERROR(OutputBitArray()) - } - - // convert to unsigned - nEncode = (nEncode > 0) ? nEncode * 2 - 1 : -nEncode * 2; - - int nOriginalKSum = BitArrayState.nKSum; - - // get the working k - int nTempK = (BitArrayState.k) ? BitArrayState.k - 1 : 0; - - // update nKSum - BitArrayState.nKSum += ((nEncode + 1) / 2) - ((BitArrayState.nKSum + 16) >> 5); - - // update k - if (BitArrayState.nKSum < K_SUM_MIN_BOUNDARY[BitArrayState.k]) - BitArrayState.k--; - else if (BitArrayState.nKSum >= K_SUM_MIN_BOUNDARY[BitArrayState.k + 1]) - BitArrayState.k++; - - // figure the pivot value - int nPivotValue = max(nOriginalKSum / 32, 1); - int nOverflow = nEncode / nPivotValue; - int nBase = nEncode - (nOverflow * nPivotValue); - - // store the overflow - if (nOverflow < (MODEL_ELEMENTS - 1)) - { - ENCODE_FAST(RANGE_WIDTH[nOverflow], RANGE_TOTAL[nOverflow], RANGE_OVERFLOW_SHIFT); - - #ifdef BUILD_RANGE_TABLE - g_aryOverflows[nOverflow]++; - g_nTotalOverflow++; - #endif - } - else - { - // store the "special" overflow (tells that perfect k is encoded next) - ENCODE_FAST(RANGE_WIDTH[MODEL_ELEMENTS - 1], RANGE_TOTAL[MODEL_ELEMENTS - 1], RANGE_OVERFLOW_SHIFT); - - #ifdef BUILD_RANGE_TABLE - g_aryOverflows[MODEL_ELEMENTS - 1]++; - g_nTotalOverflow++; - #endif - - // code the overflow using straight bits - ENCODE_DIRECT((nOverflow >> 16) & 0xFFFF, 16); - ENCODE_DIRECT(nOverflow & 0xFFFF, 16); - } - - // code the base - { - if (nPivotValue >= (1 << 16)) - { - int nPivotValueBits = 0; - while ((nPivotValue >> nPivotValueBits) > 0) { nPivotValueBits++; } - int nSplitFactor = 1 << (nPivotValueBits - 16); - - // we know that base is smaller than pivot coming into this - // however, after we divide both by an integer, they could be the same - // we account by adding one to the pivot, but this hurts compression - // by (1 / nSplitFactor) -- therefore we maximize the split factor - // that gets one added to it - - // encode the pivot as two pieces - int nPivotValueA = (nPivotValue / nSplitFactor) + 1; - int nPivotValueB = nSplitFactor; - - int nBaseA = nBase / nSplitFactor; - int nBaseB = nBase % nSplitFactor; - - { - NORMALIZE_RANGE_CODER - const int nTemp = m_RangeCoderInfo.range / nPivotValueA; - m_RangeCoderInfo.range = nTemp; - m_RangeCoderInfo.low += nTemp * nBaseA; - } - - { - NORMALIZE_RANGE_CODER - const int nTemp = m_RangeCoderInfo.range / nPivotValueB; - m_RangeCoderInfo.range = nTemp; - m_RangeCoderInfo.low += nTemp * nBaseB; - } - } - else - { - - NORMALIZE_RANGE_CODER - const int nTemp = m_RangeCoderInfo.range / nPivotValue; - m_RangeCoderInfo.range = nTemp; - m_RangeCoderInfo.low += nTemp * nBase; - } - } - - return 0; -} - -/************************************************************************************ -Flush -************************************************************************************/ -void CBitArray::FlushBitArray() -{ - // advance to a byte boundary (for alignment) - AdvanceToByteBoundary(); - - // the range coder - m_RangeCoderInfo.low = 0; // full code range - m_RangeCoderInfo.range = TOP_VALUE; - m_RangeCoderInfo.buffer = 0; - m_RangeCoderInfo.help = 0; // no bytes to follow -} - -void CBitArray::FlushState(BIT_ARRAY_STATE & BitArrayState) -{ - // k and ksum - BitArrayState.k = 10; - BitArrayState.nKSum = (1 << BitArrayState.k) * 16; -} - -/************************************************************************************ -Finalize -************************************************************************************/ -void CBitArray::Finalize() -{ - NORMALIZE_RANGE_CODER - - unsigned int nTemp = (m_RangeCoderInfo.low >> SHIFT_BITS) + 1; - - if (nTemp > 0xFF) // we have a carry - { - PUTC(m_RangeCoderInfo.buffer + 1); - for ( ; m_RangeCoderInfo.help; m_RangeCoderInfo.help--) - { - PUTC(0); - } - } - else // no carry - { - PUTC(m_RangeCoderInfo.buffer); - for ( ; m_RangeCoderInfo.help; m_RangeCoderInfo.help--) - { - PUTC(((unsigned char) 0xFF)); - } - } - - // we must output these bytes so the decoder can properly work at the end of the stream - PUTC(nTemp & 0xFF); - PUTC(0); - PUTC(0); - PUTC(0); -} - -/************************************************************************************ -Build a range table (for development / debugging) -************************************************************************************/ -#ifdef BUILD_RANGE_TABLE -void CBitArray::OutputRangeTable() -{ - int z; - - if (g_nTotalOverflow == 0) return; - - int nTotal = 0; - int aryWidth[256]; ZeroMemory(aryWidth, 256 * 4); - for (z = 0; z < MODEL_ELEMENTS; z++) - { - aryWidth[z] = int(((float(g_aryOverflows[z]) * float(65536)) + (g_nTotalOverflow / 2)) / float(g_nTotalOverflow)); - if (aryWidth[z] == 0) aryWidth[z] = 1; - nTotal += aryWidth[z]; - } - - z = 0; - while (nTotal > 65536) - { - if (aryWidth[z] != 1) - { - aryWidth[z]--; - nTotal--; - } - z++; - if (z == MODEL_ELEMENTS) z = 0; - } - - z = 0; - while (nTotal < 65536) - { - aryWidth[z++]++; - nTotal++; - if (z == MODEL_ELEMENTS) z = 0; - } - - int aryTotal[256]; ZeroMemory(aryTotal, 256 * 4); - for (z = 0; z < MODEL_ELEMENTS; z++) - { - for (int q = 0; q < z; q++) - { - aryTotal[z] += aryWidth[q]; - } - } - - TCHAR buf[1024]; - _stprintf(buf, _T("const uint32 RANGE_TOTAL[%d] = {"), MODEL_ELEMENTS); - ODS(buf); - for (z = 0; z < MODEL_ELEMENTS; z++) - { - _stprintf(buf, _T("%d,"), aryTotal[z]); - OutputDebugString(buf); - } - ODS(_T("};\n")); - - _stprintf(buf, _T("const uint32 RANGE_WIDTH[%d] = {"), MODEL_ELEMENTS); - ODS(buf); - for (z = 0; z < MODEL_ELEMENTS; z++) - { - _stprintf(buf, _T("%d,"), aryWidth[z]); - OutputDebugString(buf); - } - ODS(_T("};\n\n")); -} -#endif // #ifdef BUILD_RANGE_TABLE diff --git a/MAC_SDK/Source/MACLib/BitArray.h b/MAC_SDK/Source/MACLib/BitArray.h deleted file mode 100644 index 2f4cde7..0000000 --- a/MAC_SDK/Source/MACLib/BitArray.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef APE_BITARRAY_H -#define APE_BITARRAY_H - -#include "IO.h" -#include "MD5.h" - -//#define BUILD_RANGE_TABLE - -struct RANGE_CODER_STRUCT_COMPRESS -{ - unsigned int low; // low end of interval - unsigned int range; // length of interval - unsigned int help; // bytes_to_follow resp. intermediate value - unsigned char buffer; // buffer for input / output -}; - -struct BIT_ARRAY_STATE -{ - uint32 k; - uint32 nKSum; -}; - -class CBitArray -{ -public: - - // construction / destruction - CBitArray(CIO *pIO); - ~CBitArray(); - - // encoding - int EncodeUnsignedLong(unsigned int n); - int EncodeValue(int nEncode, BIT_ARRAY_STATE & BitArrayState); - int EncodeBits(unsigned int nValue, int nBits); - - // output (saving) - int OutputBitArray(BOOL bFinalize = FALSE); - - // other functions - void Finalize(); - void AdvanceToByteBoundary(); - inline uint32 GetCurrentBitIndex() { return m_nCurrentBitIndex; } - void FlushState(BIT_ARRAY_STATE & BitArrayState); - void FlushBitArray(); - inline CMD5Helper & GetMD5Helper() { return m_MD5; } - -private: - - // data members - uint32 * m_pBitArray; - CIO * m_pIO; - uint32 m_nCurrentBitIndex; - RANGE_CODER_STRUCT_COMPRESS m_RangeCoderInfo; - CMD5Helper m_MD5; - -#ifdef BUILD_RANGE_TABLE - void OutputRangeTable(); -#endif - -}; - -#endif // #ifndef APE_BITARRAY_H diff --git a/MAC_SDK/Source/MACLib/MACLib.cpp b/MAC_SDK/Source/MACLib/MACLib.cpp deleted file mode 100644 index db26bd8..0000000 --- a/MAC_SDK/Source/MACLib/MACLib.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include "All.h" -#include "MACLib.h" - -#include "APECompress.h" -#include "APECompressCreate.h" -#include "APECompressCore.h" -#include "APECompress.h" -#include "APEDecompress.h" -#include "APEInfo.h" -#include "APELink.h" - -#ifdef BACKWARDS_COMPATIBILITY - #include "Old/APEDecompressOld.h" -#endif - -IAPEDecompress * CreateIAPEDecompressCore(CAPEInfo * pAPEInfo, int nStartBlock, int nFinishBlock, int * pErrorCode) -{ - IAPEDecompress * pAPEDecompress = NULL; - if (pAPEInfo != NULL && *pErrorCode == ERROR_SUCCESS) - { - try - { - if (pAPEInfo->GetInfo(APE_INFO_FILE_VERSION) >= 3930) - pAPEDecompress = new CAPEDecompress(pErrorCode, pAPEInfo, nStartBlock, nFinishBlock); -#ifdef BACKWARDS_COMPATIBILITY - else - pAPEDecompress = new CAPEDecompressOld(pErrorCode, pAPEInfo, nStartBlock, nFinishBlock); -#endif - - if (pAPEDecompress == NULL || *pErrorCode != ERROR_SUCCESS) - { - SAFE_DELETE(pAPEDecompress) - } - } - catch(...) - { - SAFE_DELETE(pAPEDecompress) - *pErrorCode = ERROR_UNDEFINED; - } - } - - return pAPEDecompress; -} - -#ifdef IO_CLASS_NAME -IAPEDecompress * __stdcall CreateIAPEDecompress(const str_utf16 * pFilename, int * pErrorCode) -{ - // error check the parameters - if ((pFilename == NULL) || (wcslen(pFilename) == 0)) - { - if (pErrorCode) *pErrorCode = ERROR_BAD_PARAMETER; - return NULL; - } - - // variables - int nErrorCode = ERROR_UNDEFINED; - CAPEInfo * pAPEInfo = NULL; - int nStartBlock = -1; int nFinishBlock = -1; - - // get the extension - const str_utf16 * pExtension = &pFilename[wcslen(pFilename)]; - while ((pExtension > pFilename) && (*pExtension != '.')) - pExtension--; - - // take the appropriate action (based on the extension) - if (wcsicmp(pExtension, L".apl") == 0) - { - // "link" file (.apl linked large APE file) - CAPELink APELink(pFilename); - if (APELink.GetIsLinkFile()) - { -#ifndef NO_TAG - pAPEInfo = new CAPEInfo(&nErrorCode, APELink.GetImageFilename(), new CAPETag(pFilename, TRUE)); -#else - pAPEInfo = new CAPEInfo(&nErrorCode, APELink.GetImageFilename(), NULL); -#endif - nStartBlock = APELink.GetStartBlock(); nFinishBlock = APELink.GetFinishBlock(); - } - } - else if ((wcsicmp(pExtension, L".mac") == 0) || (wcsicmp(pExtension, L".ape") == 0)) - { - // plain .ape file - pAPEInfo = new CAPEInfo(&nErrorCode, pFilename, NULL, 1); - } - - // fail if we couldn't get the file information - if (pAPEInfo == NULL) - { - if (pErrorCode) *pErrorCode = ERROR_INVALID_INPUT_FILE; - return NULL; - } - - // create and return - IAPEDecompress * pAPEDecompress = CreateIAPEDecompressCore(pAPEInfo, nStartBlock, nFinishBlock, &nErrorCode); - if (pErrorCode) *pErrorCode = nErrorCode; - return pAPEDecompress; -} -#endif - -IAPEDecompress * __stdcall CreateIAPEDecompressEx(CIO * pIO, int * pErrorCode) -{ - int nErrorCode = ERROR_UNDEFINED; - CAPEInfo * pAPEInfo = new CAPEInfo(&nErrorCode, pIO); - IAPEDecompress * pAPEDecompress = CreateIAPEDecompressCore(pAPEInfo, -1, -1, &nErrorCode); - if (pErrorCode) *pErrorCode = nErrorCode; - return pAPEDecompress; -} - - -IAPEDecompress * __stdcall CreateIAPEDecompressEx2(CAPEInfo * pAPEInfo, int nStartBlock, int nFinishBlock, int * pErrorCode) -{ - int nErrorCode = ERROR_SUCCESS; - IAPEDecompress * pAPEDecompress = CreateIAPEDecompressCore(pAPEInfo, nStartBlock, nFinishBlock, &nErrorCode); - if (pErrorCode) *pErrorCode = nErrorCode; - return pAPEDecompress; -} - -IAPECompress * __stdcall CreateIAPECompress(int * pErrorCode) -{ - if (pErrorCode) - *pErrorCode = ERROR_SUCCESS; - - return new CAPECompress(); -} - -int __stdcall FillWaveFormatEx(WAVEFORMATEX * pWaveFormatEx, int nSampleRate, int nBitsPerSample, int nChannels) -{ - pWaveFormatEx->cbSize = 0; - pWaveFormatEx->nSamplesPerSec = nSampleRate; - pWaveFormatEx->wBitsPerSample = nBitsPerSample; - pWaveFormatEx->nChannels = nChannels; - pWaveFormatEx->wFormatTag = 1; - - pWaveFormatEx->nBlockAlign = (pWaveFormatEx->wBitsPerSample / 8) * pWaveFormatEx->nChannels; - pWaveFormatEx->nAvgBytesPerSec = pWaveFormatEx->nBlockAlign * pWaveFormatEx->nSamplesPerSec; - - return ERROR_SUCCESS; -} - -int __stdcall FillWaveHeader(WAVE_HEADER * pWAVHeader, int nAudioBytes, WAVEFORMATEX * pWaveFormatEx, int nTerminatingBytes) -{ - try - { - // RIFF header - memcpy(pWAVHeader->cRIFFHeader, "RIFF", 4); - pWAVHeader->nRIFFBytes = (nAudioBytes + 44) - 8 + nTerminatingBytes; - - // format header - memcpy(pWAVHeader->cDataTypeID, "WAVE", 4); - memcpy(pWAVHeader->cFormatHeader, "fmt ", 4); - - // the format chunk is the first 16 bytes of a waveformatex - pWAVHeader->nFormatBytes = 16; - memcpy(&pWAVHeader->nFormatTag, pWaveFormatEx, 16); - - // the data header - memcpy(pWAVHeader->cDataHeader, "data", 4); - pWAVHeader->nDataBytes = nAudioBytes; - - return ERROR_SUCCESS; - } - catch(...) { return ERROR_UNDEFINED; } -} \ No newline at end of file diff --git a/MAC_SDK/Source/MACLib/MACLib.dsp b/MAC_SDK/Source/MACLib/MACLib.dsp deleted file mode 100644 index 0edca6e..0000000 --- a/MAC_SDK/Source/MACLib/MACLib.dsp +++ /dev/null @@ -1,462 +0,0 @@ -# Microsoft Developer Studio Project File - Name="MACLib" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=MACLib - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "MACLib.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "MACLib.mak" CFG="MACLib - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "MACLib - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "MACLib - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName ""$/Monkey's Audio/MACLib", SCAAAAAA" -# PROP Scc_LocalPath "." -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "MACLib - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /G6 /MT /W3 /GX /Ox /Ot /Og /Oi /Ob2 /I "..\Shared" /D "WIN32" /D "NDEBUG" /D "_LIB" /D "_UNICODE" /D "UNICODE" /FR /YX"all.h" /FD /c -# SUBTRACT CPP /Oa -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo -# Begin Special Build Tool -ProjDir=. -SOURCE="$(InputPath)" -PreLink_Desc=Building assembly... -PreLink_Cmds=cd $(ProjDir)\Assembly nasmw -d WIN32 -f win32 -o Assembly.obj Assembly.nas -# End Special Build Tool - -!ELSEIF "$(CFG)" == "MACLib - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\Shared" /D "WIN32" /D "_DEBUG" /D "_LIB" /D "_UNICODE" /D "UNICODE" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo -# Begin Special Build Tool -ProjDir=. -SOURCE="$(InputPath)" -PreLink_Desc=Building assembly... -PreLink_Cmds=cd $(ProjDir)\Assembly nasmw -d WIN32 -f win32 -o Assembly.obj Assembly.nas -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "MACLib - Win32 Release" -# Name "MACLib - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Group "Compress" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\APECompress.cpp -# End Source File -# Begin Source File - -SOURCE=.\APECompressCore.cpp -# End Source File -# Begin Source File - -SOURCE=.\APECompressCreate.cpp -# End Source File -# Begin Source File - -SOURCE=.\BitArray.cpp -# End Source File -# End Group -# Begin Group "Decompress" - -# PROP Default_Filter "" -# Begin Group "Old" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\Old\Anti-Predictor.cpp" -# End Source File -# Begin Source File - -SOURCE=.\Old\AntiPredictorExtraHigh.cpp -# End Source File -# Begin Source File - -SOURCE=.\Old\AntiPredictorFast.cpp -# End Source File -# Begin Source File - -SOURCE=.\Old\AntiPredictorHigh.cpp -# End Source File -# Begin Source File - -SOURCE=.\Old\AntiPredictorNormal.cpp -# End Source File -# Begin Source File - -SOURCE=.\Old\APEDecompressCore.cpp -# End Source File -# Begin Source File - -SOURCE=.\Old\APEDecompressOld.cpp -# End Source File -# Begin Source File - -SOURCE=.\Old\UnBitArrayOld.cpp -# End Source File -# Begin Source File - -SOURCE=.\Old\UnMAC.cpp -# End Source File -# End Group -# Begin Source File - -SOURCE=.\APEDecompress.cpp -# End Source File -# Begin Source File - -SOURCE=.\UnBitArray.cpp -# End Source File -# Begin Source File - -SOURCE=.\UnBitArrayBase.cpp -# End Source File -# End Group -# Begin Group "Info" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\APEHeader.cpp -# End Source File -# Begin Source File - -SOURCE=.\APEInfo.cpp -# End Source File -# Begin Source File - -SOURCE=.\APELink.cpp -# End Source File -# Begin Source File - -SOURCE=.\APETag.cpp -# End Source File -# Begin Source File - -SOURCE=.\WAVInputSource.cpp -# End Source File -# End Group -# Begin Group "Tools" - -# PROP Default_Filter "" -# Begin Group "IO" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\Shared\StdLibFileIO.cpp -# End Source File -# Begin Source File - -SOURCE=..\Shared\WinFileIO.cpp -# End Source File -# End Group -# Begin Source File - -SOURCE=..\Shared\CharacterHelper.cpp -# End Source File -# Begin Source File - -SOURCE=..\Shared\CircleBuffer.cpp -# End Source File -# Begin Source File - -SOURCE=..\Shared\GlobalFunctions.cpp -# End Source File -# Begin Source File - -SOURCE=.\MACProgressHelper.cpp -# End Source File -# Begin Source File - -SOURCE=.\MD5.cpp -# End Source File -# Begin Source File - -SOURCE=.\Prepare.cpp -# End Source File -# End Group -# Begin Group "Prediction" - -# PROP Default_Filter "" -# Begin Group "Filters" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\NNFilter.cpp -# End Source File -# End Group -# Begin Source File - -SOURCE=.\NewPredictor.cpp -# End Source File -# End Group -# Begin Source File - -SOURCE=.\APESimple.cpp -# End Source File -# Begin Source File - -SOURCE=.\MACLib.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Group "Compress (h)" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\APECompress.h -# End Source File -# Begin Source File - -SOURCE=.\APECompressCore.h -# End Source File -# Begin Source File - -SOURCE=.\APECompressCreate.h -# End Source File -# Begin Source File - -SOURCE=.\BitArray.h -# End Source File -# End Group -# Begin Group "Decompress (h)" - -# PROP Default_Filter "" -# Begin Group "Old (h)" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\Old\Anti-Predictor.h" -# End Source File -# Begin Source File - -SOURCE=.\Old\APEDecompressCore.h -# End Source File -# Begin Source File - -SOURCE=.\Old\APEDecompressOld.h -# End Source File -# Begin Source File - -SOURCE=.\Old\UnBitArrayOld.h -# End Source File -# Begin Source File - -SOURCE=.\Old\UnMAC.h -# End Source File -# End Group -# Begin Source File - -SOURCE=.\APEDecompress.h -# End Source File -# Begin Source File - -SOURCE=.\UnBitArray.h -# End Source File -# Begin Source File - -SOURCE=.\UnBitArrayBase.h -# End Source File -# End Group -# Begin Group "Info (h)" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\APEHeader.h -# End Source File -# Begin Source File - -SOURCE=.\APEInfo.h -# End Source File -# Begin Source File - -SOURCE=.\APELink.h -# End Source File -# Begin Source File - -SOURCE=.\APETag.h -# End Source File -# Begin Source File - -SOURCE=.\WAVInputSource.h -# End Source File -# End Group -# Begin Group "Tools (h)" - -# PROP Default_Filter "" -# Begin Group "IO (h)" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\Shared\IO.h -# End Source File -# Begin Source File - -SOURCE=..\Shared\StdLibFileIO.h -# End Source File -# Begin Source File - -SOURCE=..\Shared\WinFileIO.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\Shared\CharacterHelper.h -# End Source File -# Begin Source File - -SOURCE=..\Shared\CircleBuffer.h -# End Source File -# Begin Source File - -SOURCE=..\Shared\GlobalFunctions.h -# End Source File -# Begin Source File - -SOURCE=.\MACProgressHelper.h -# End Source File -# Begin Source File - -SOURCE=.\md5.h -# End Source File -# Begin Source File - -SOURCE=..\Shared\NoWindows.h -# End Source File -# Begin Source File - -SOURCE=.\Prepare.h -# End Source File -# Begin Source File - -SOURCE=..\Shared\SmartPtr.h -# End Source File -# End Group -# Begin Group "Prediction (h)" - -# PROP Default_Filter "" -# Begin Group "Filters (h)" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\NNFilter.h -# End Source File -# Begin Source File - -SOURCE=..\Shared\RollBuffer.h -# End Source File -# Begin Source File - -SOURCE=.\ScaledFirstOrderFilter.h -# End Source File -# End Group -# Begin Source File - -SOURCE=.\NewPredictor.h -# End Source File -# Begin Source File - -SOURCE=.\Predictor.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\Shared\All.h -# End Source File -# Begin Source File - -SOURCE=.\Assembly\Assembly.h -# End Source File -# Begin Source File - -SOURCE=.\MACLib.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\Credits.txt -# End Source File -# Begin Source File - -SOURCE=..\History.txt -# End Source File -# Begin Source File - -SOURCE="..\To Do.txt" -# End Source File -# Begin Source File - -SOURCE=.\Assembly\Assembly.obj -# End Source File -# End Target -# End Project diff --git a/MAC_SDK/Source/MACLib/MACLib.h b/MAC_SDK/Source/MACLib/MACLib.h deleted file mode 100644 index 5a70cd3..0000000 --- a/MAC_SDK/Source/MACLib/MACLib.h +++ /dev/null @@ -1,452 +0,0 @@ -/***************************************************************************************** -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) - ////////////////////////////////////////////////////////////////////////////////////////////// - -#ifdef IO_CLASS_NAME - 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; -#endif - - 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 diff --git a/MAC_SDK/Source/MACLib/MACLib.sln b/MAC_SDK/Source/MACLib/MACLib.sln deleted file mode 100644 index c939473..0000000 --- a/MAC_SDK/Source/MACLib/MACLib.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MACLib", "MACLib.vcproj", "{0B9C97D4-61B8-4294-A1DF-BA90752A1779}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sample 2", "..\..\Decompress\Sample 2\Sample 2.vcproj", "{E7B72EF2-1C5A-45EF-BA35-6094BCF560B1}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|Win32.ActiveCfg = Debug|Win32 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|Win32.Build.0 = Debug|Win32 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|x64.ActiveCfg = Debug|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Debug|x64.Build.0 = Debug|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|Win32.ActiveCfg = Release|Win32 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|Win32.Build.0 = Release|Win32 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|x64.ActiveCfg = Release|x64 - {0B9C97D4-61B8-4294-A1DF-BA90752A1779}.Release|x64.Build.0 = Release|x64 - {E7B72EF2-1C5A-45EF-BA35-6094BCF560B1}.Debug|Win32.ActiveCfg = Debug|Win32 - {E7B72EF2-1C5A-45EF-BA35-6094BCF560B1}.Debug|Win32.Build.0 = Debug|Win32 - {E7B72EF2-1C5A-45EF-BA35-6094BCF560B1}.Debug|x64.ActiveCfg = Debug|x64 - {E7B72EF2-1C5A-45EF-BA35-6094BCF560B1}.Release|Win32.ActiveCfg = Release|Win32 - {E7B72EF2-1C5A-45EF-BA35-6094BCF560B1}.Release|Win32.Build.0 = Release|Win32 - {E7B72EF2-1C5A-45EF-BA35-6094BCF560B1}.Release|x64.ActiveCfg = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/MAC_SDK/Source/MACLib/MACLib.vcproj b/MAC_SDK/Source/MACLib/MACLib.vcproj deleted file mode 100644 index 5302081..0000000 --- a/MAC_SDK/Source/MACLib/MACLib.vcproj +++ /dev/null @@ -1,1334 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MAC_SDK/Source/MACLib/MACLib.vcproj.7.10.old b/MAC_SDK/Source/MACLib/MACLib.vcproj.7.10.old deleted file mode 100644 index 4bdb285..0000000 --- a/MAC_SDK/Source/MACLib/MACLib.vcproj.7.10.old +++ /dev/null @@ -1,1019 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MAC_SDK/Source/MACLib/MACLib.vcxproj b/MAC_SDK/Source/MACLib/MACLib.vcxproj deleted file mode 100644 index 6bbb8da..0000000 --- a/MAC_SDK/Source/MACLib/MACLib.vcxproj +++ /dev/null @@ -1,581 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {0B9C97D4-61B8-4294-A1DF-BA90752A1779} - MACLib - 10.0.16299.0 - - - - StaticLibrary - false - Unicode - v141 - - - StaticLibrary - false - Unicode - v141 - - - StaticLibrary - false - Unicode - v141 - - - StaticLibrary - false - Unicode - v141 - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)..\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)..\obj\$(ProjectName)\$(Platform)\$(Configuration)\ - $(SolutionDir)..\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)..\obj\$(ProjectName)\$(Platform)\$(Configuration)\ - $(SolutionDir)..\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)..\obj\$(ProjectName)\$(Platform)\$(Configuration)\ - $(SolutionDir)..\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)..\obj\$(ProjectName)\$(Platform)\$(Configuration)\ - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - Disabled - ..\Shared;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;UNICODE;NO_TAG;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - .\Debug/ - .\Debug/ - .\Debug/ - true - Level3 - true - EditAndContinue - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Building assembly... - cd "$(ProjectDir)"Assembly -nasmw -d WIN32 -f win32 -o Assembly.obj Assembly.nas - - - - true - - - - - X64 - - - Disabled - ..\Shared;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;UNICODE;_CRT_SECURE_NO_WARNINGS;NO_TAG;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - Level3 - true - ProgramDatabase - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - - - - - true - - - - - Full - AnySuitable - true - Speed - ..\Shared;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;UNICODE;_CRT_SECURE_NO_WARNINGS;NO_TAG;%(PreprocessorDefinitions) - MultiThreadedDLL - - - all.h - .\Release/ - .\Release/ - .\Release/ - true - Level3 - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Building assembly... - cd "$(ProjectDir)"Assembly -nasmw -d WIN32 -f win32 -o Assembly.obj Assembly.nas - - - - true - - - - - X64 - - - Full - AnySuitable - true - Speed - true - true - ..\Shared;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;UNICODE;_CRT_SECURE_NO_WARNINGS;NO_TAG;%(PreprocessorDefinitions) - MultiThreadedDLL - false - StreamingSIMDExtensions - Fast - - - all.h - .\x64\Release/ - .\x64\Release/ - .\x64\Release/ - true - Level3 - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - - - - - true - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - Full - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Document - true - true - cd "$(ProjectDir)"Assembly -nasmw -d WIN32 -f win32 -o Assembly.obj Assembly.nas - - $(ProjectDir)Assembly/Assembly.obj - $(ProjectDir)Assembly/Assembly.nas - $(ProjectDir)Assembly/Assembly.obj - $(ProjectDir)Assembly/Assembly.nas - cd "$(ProjectDir)"Assembly -nasmw -d WIN32 -f win32 -o Assembly.obj Assembly.nas - - - - true - cd "$(ProjectDir)"Assembly -nasmw -d WIN32 -f win64 -o Assembly64.obj Assembly64.nas - - $(ProjectDir)Assembly/Assembly64.nas;%(AdditionalInputs) - $(ProjectDir)Assembly/Assembly64.obj;%(Outputs) - true - Calling assembler - cd "$(ProjectDir)"Assembly -nasmw -d WIN32 -f win64 -o Assembly64.obj Assembly64.nas - - $(ProjectDir)Assembly/Assembly64.nas - $(ProjectDir)Assembly/Assembly64.obj - - - - - - - - - - true - true - - - - - - \ No newline at end of file diff --git a/MAC_SDK/Source/MACLib/MACProgressHelper.cpp b/MAC_SDK/Source/MACLib/MACProgressHelper.cpp deleted file mode 100644 index 410dd96..0000000 --- a/MAC_SDK/Source/MACLib/MACProgressHelper.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "All.h" -#include "MACProgressHelper.h" - -CMACProgressHelper::CMACProgressHelper(int nTotalSteps, int * pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int * pKillFlag) -{ - m_pKillFlag = pKillFlag; - - m_bUseCallback = FALSE; - if (ProgressCallback != NULL) - { - m_bUseCallback = TRUE; - m_CallbackFunction = ProgressCallback; - } - - m_pPercentageDone = pPercentageDone; - - m_nTotalSteps = nTotalSteps; - m_nCurrentStep = 0; - m_nLastCallbackFiredPercentageDone = 0; - - UpdateProgress(0); -} - -CMACProgressHelper::~CMACProgressHelper() -{ - -} - -void CMACProgressHelper::UpdateProgress(int nCurrentStep, BOOL bForceUpdate) -{ - // update the step - if (nCurrentStep == -1) - m_nCurrentStep++; - else - m_nCurrentStep = nCurrentStep; - - // figure the percentage done - float fPercentageDone = float(m_nCurrentStep) / float(max(m_nTotalSteps, 1)); - int nPercentageDone = (int) (fPercentageDone * 1000 * 100); - if (nPercentageDone > 100000) nPercentageDone = 100000; - - // update the percent done pointer - if (m_pPercentageDone) - { - *m_pPercentageDone = nPercentageDone; - } - - // fire the callback - if (m_bUseCallback) - { - if (bForceUpdate || (nPercentageDone - m_nLastCallbackFiredPercentageDone) >= 1000) - { - m_CallbackFunction(nPercentageDone); - m_nLastCallbackFiredPercentageDone = nPercentageDone; - } - } -} - -int CMACProgressHelper::ProcessKillFlag(BOOL bSleep) -{ - // process any messages (allows repaint, etc.) - if (bSleep) - { - PUMP_MESSAGE_LOOP - } - - if (m_pKillFlag) - { - while (*m_pKillFlag == KILL_FLAG_PAUSE) - { - SLEEP(50); - PUMP_MESSAGE_LOOP - } - - if ((*m_pKillFlag != KILL_FLAG_CONTINUE) && (*m_pKillFlag != KILL_FLAG_PAUSE)) - { - return -1; - } - } - - return ERROR_SUCCESS; -} diff --git a/MAC_SDK/Source/MACLib/MACProgressHelper.h b/MAC_SDK/Source/MACLib/MACProgressHelper.h deleted file mode 100644 index 48c08d5..0000000 --- a/MAC_SDK/Source/MACLib/MACProgressHelper.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef APE_MACPROGRESSHELPER_H -#define APE_MACPROGRESSHELPER_H - -#define KILL_FLAG_CONTINUE 0 -#define KILL_FLAG_PAUSE -1 -#define KILL_FLAG_STOP 1 - -typedef void (__stdcall * APE_PROGRESS_CALLBACK) (int); - -class CMACProgressHelper -{ -public: - - CMACProgressHelper(int nTotalSteps, int *pPercentageDone, APE_PROGRESS_CALLBACK ProgressCallback, int *pKillFlag); - virtual ~CMACProgressHelper(); - - void UpdateProgress(int nCurrentStep = -1, BOOL bForceUpdate = FALSE); - void UpdateProgressComplete() { UpdateProgress(m_nTotalSteps, TRUE); } - - int ProcessKillFlag(BOOL bSleep = TRUE); - -private: - - BOOL m_bUseCallback; - APE_PROGRESS_CALLBACK m_CallbackFunction; - - int *m_pPercentageDone; - - int m_nTotalSteps; - int m_nCurrentStep; - int m_nLastCallbackFiredPercentageDone; - - int *m_pKillFlag; -}; - -#endif // #ifndef APE_MACPROGRESSHELPER_H - diff --git a/MAC_SDK/Source/MACLib/MD5.cpp b/MAC_SDK/Source/MACLib/MD5.cpp deleted file mode 100644 index afd6be6..0000000 --- a/MAC_SDK/Source/MACLib/MD5.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/***************************************************************************** -* -* "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm". -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -*****************************************************************************/ - -#include "All.h" -#include -#include "MD5.h" - - -#if __BYTE_ORDER == __BIG_ENDIAN -/* - * Block copy and convert byte order to little-endian. - * dst must be 32bit aligned. - * Length is the number of 32bit words - */ -static void -CopyToLittleEndian ( uint32_t* dst, - const uint8_t* src, - size_t length ) -{ - for ( ; length--; src += 4; dst++ ) { - *dst = (( (uint32_t) src [3] ) << 24) | - (( (uint32_t) src [2] ) << 16) | - (( (uint32_t) src [1] ) << 8) | - (( (uint32_t) src [0] ) << 0); - - - } -} -#endif - - -/* - Assembler versions of __MD5Transform, MD5Init and MD5Update - currently exist for x86 and little-endian ARM. - For other targets, we need to use the C versions below. -*/ - -#if !(defined (__i386__) || ((defined (__arm__) && (__BYTE_ORDER == __LITTLE_ENDIAN)))) - -/* - Initialise the MD5 context. -*/ -void -MD5Init ( MD5_CTX* context ) -{ - context -> count [0] = 0; - context -> count [1] = 0; - - context -> state [0] = 0x67452301; /* Load magic constants. */ - context -> state [1] = 0xefcdab89; - context -> state [2] = 0x98badcfe; - context -> state [3] = 0x10325476; -} - -#define ROTATE_LEFT(x, n) ((x << n) | (x >> (32-n))) - -#define F(x, y, z) (z ^ (x & (y ^ z))) -#define G(x, y, z) (y ^ (z & (x ^ y))) -#define H(x, y, z) (x ^ y ^ z) -#define I(x, y, z) (y ^ (x | ~z)) - -#define FF(a, b, c, d, x, s, ac) { (a) += F (b, c, d) + (x) + (uint32_t)(ac); (a) = ROTATE_LEFT (a, s); (a) += (b); } -#define GG(a, b, c, d, x, s, ac) { (a) += G (b, c, d) + (x) + (uint32_t)(ac); (a) = ROTATE_LEFT (a, s); (a) += (b); } -#define HH(a, b, c, d, x, s, ac) { (a) += H (b, c, d) + (x) + (uint32_t)(ac); (a) = ROTATE_LEFT (a, s); (a) += (b); } -#define II(a, b, c, d, x, s, ac) { (a) += I (b, c, d) + (x) + (uint32_t)(ac); (a) = ROTATE_LEFT (a, s); (a) += (b); } - -static void -__MD5Transform ( uint32_t state [4], - const uint8_t* in, - int repeat ) -{ - const uint32_t* x; - uint32_t a = state [0]; - uint32_t b = state [1]; - uint32_t c = state [2]; - uint32_t d = state [3]; - - for ( ; repeat; repeat-- ) { - uint32_t tempBuffer [16]; -#if __BYTE_ORDER == __BIG_ENDIAN - - CopyToLittleEndian (tempBuffer, in, 16); - x = tempBuffer; -#else - if ( (unsigned int)in & 3 ) { - memcpy ( tempBuffer, in, 64 ); - x = tempBuffer; - } - else { - x = (const uint32_t*) in; - } -#endif - - FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */ /* Round 1 */ - FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], 7, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], 12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], 17, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], 22, 0x49b40821); /* 16 */ - - GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */ /* Round 2 */ - GG (d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], 9, 0x02441453); /* 22 */ - GG (c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */ - - HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */ /* Round 3 */ - HH (d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], 23, 0x04881d05); /* 44 */ - HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */ - - II (a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */ /* Round 4 */ - II (d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */ - - state [0] = a = a + state [0]; - state [1] = b = b + state [1]; - state [2] = c = c + state [2]; - state [3] = d = d + state [3]; - - in += 64; - } -} - - -/* - MD5 block update operation: - Process another sub-string of the message and update the context. -*/ - -void -MD5Update ( MD5_CTX* context, - const uint8_t* input, - size_t inputBytes ) -{ - int byteIndex; - unsigned int partLen; - int len; - int i; - - /* Compute number of bytes mod 64 */ - byteIndex = (context -> count[0] >> 3) & 0x3F; - - /* Update number of bits: count += 8 * inputBytes */ - if ( (context -> count [0] += inputBytes << 3) < (inputBytes << 3) ) - context -> count [1]++; - context -> count [1] += inputBytes >> (32 - 3); - - partLen = (64 - byteIndex); - - /* Transform as many times as possible. */ - if ( inputBytes >= partLen ) { - memcpy ( context -> buffer + byteIndex, input, partLen ); - __MD5Transform ( context -> state, (const uint8_t*) context -> buffer, 1 ); - len = ( inputBytes - partLen ) >> 6; - __MD5Transform ( context -> state, input + partLen, len ); - i = partLen + (len << 6); - byteIndex = 0; - } - else { - i = 0; - } - - /* Buffer remaining input */ - memcpy ( (context -> buffer) + byteIndex, input + i, inputBytes - i ); -} - -#endif - - -void -MD5Final ( uint8_t digest [16], - MD5_CTX* context ) -{ - static uint8_t finalBlock [64]; - uint32_t bits [2]; - int byteIndex; - int finalBlockLength; - - byteIndex = (context -> count[0] >> 3) & 0x3F; - finalBlockLength = (byteIndex < 56 ? 56 : 120) - byteIndex; - finalBlock[0] = 0x80; - -#if __BYTE_ORDER == __BIG_ENDIAN - CopyToLittleEndian ( bits, (const uint8_t*) context -> count, 2 ); -#else - memcpy ( bits, context->count, 8 ); -#endif - - MD5Update ( context, finalBlock, finalBlockLength ); - MD5Update ( context, (const uint8_t*) bits, 8 ); - -#if __BYTE_ORDER == __BIG_ENDIAN - CopyToLittleEndian ( (uint32_t*) digest, (const uint8_t*) context -> state, 4 ); -#else - memcpy ( digest, context -> state, 16 ); -#endif - - memset ( context, 0, sizeof (*context) ); -} - diff --git a/MAC_SDK/Source/MACLib/MultichannelNNFilter.h b/MAC_SDK/Source/MACLib/MultichannelNNFilter.h deleted file mode 100644 index df66c3f..0000000 --- a/MAC_SDK/Source/MACLib/MultichannelNNFilter.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef APE_MULTICHANNEL_NNFILTER_H -#define APE_MULTICHANNEL_NNFILTER_H - -#include "NNFilter.h" - -class CMultichannelNNFilter -{ -public: - - CMultichannelNNFilter(int nOrder1, int nOrder2, int nShift) - { - m_pNNFilterA = new CNNFilter(nOrder1 + nOrder2, 11, 3980); - m_pNNFilterB = new CNNFilter(nOrder1 + nOrder2, 11, 3980); - - m_rbA.Create(NN_WINDOW_ELEMENTS, nOrder1 + nOrder2 + 1); - m_rbB.Create(NN_WINDOW_ELEMENTS, nOrder1 + nOrder2 + 1); - - m_nShift = nShift; - - m_nOrder1 = nOrder1; - } - - - ~CMultichannelNNFilter() - { - SAFE_DELETE(m_pNNFilterA) - SAFE_DELETE(m_pNNFilterB) - } - - void Flush() - { - m_pNNFilterA->Flush(); - m_pNNFilterB->Flush(); - - m_rbA.Flush(); - m_rbB.Flush(); - - } - - inline void Compress(int & nA, int & nB) - { - if (m_nShift <= 0) - return; - - m_rbA[0] = GetSaturatedShortFromInt(nA); m_rbB[0] = GetSaturatedShortFromInt(nB); - m_rbA[-m_nOrder1 - 1] = m_rbB[-1]; m_rbB[-m_nOrder1 - 1] = m_rbA[0]; - - nA -= (m_pNNFilterA->GetPrediction(&m_rbA[-1]) >> m_nShift); - nB -= (m_pNNFilterB->GetPrediction(&m_rbB[-1]) >> m_nShift); - - m_pNNFilterA->AdaptAfterPrediction(&m_rbA[-1], -m_nOrder1, nA); - m_pNNFilterB->AdaptAfterPrediction(&m_rbB[-1], -m_nOrder1, nB); - - m_rbA.IncrementSafe(); m_rbB.IncrementSafe(); - } - - inline void Decompress(int & nA, int & nB) - { - if (m_nShift <= 0) - return; - - m_rbA[-m_nOrder1 - 1] = m_rbB[-1]; - int nOutputA = nA + (m_pNNFilterA->GetPrediction(&m_rbA[-1]) >> m_nShift); - m_rbA[0] = GetSaturatedShortFromInt(nOutputA); - - m_rbB[-m_nOrder1 - 1] = m_rbA[0]; - int nOutputB = nB + (m_pNNFilterB->GetPrediction(&m_rbB[-1]) >> m_nShift); - m_rbB[0] = GetSaturatedShortFromInt(nOutputB); - - m_pNNFilterA->AdaptAfterPrediction(&m_rbA[-1], -m_nOrder1, nA); - m_pNNFilterB->AdaptAfterPrediction(&m_rbB[-1], -m_nOrder1, nB); - - m_rbA.IncrementSafe(); m_rbB.IncrementSafe(); - - nA = nOutputA; nB = nOutputB; - } - -protected: - - CNNFilter * m_pNNFilterA; - CNNFilter * m_pNNFilterB; - - int m_nShift; - int m_nOrder1; - - CRollBuffer m_rbA; - CRollBuffer m_rbB; - - inline short GetSaturatedShortFromInt(int nValue) const - { - return short((nValue == short(nValue)) ? nValue : (nValue >> 31) ^ 0x7FFF); - } -}; - -#endif // #ifndef APE_MULTICHANNEL_NNFILTER_H diff --git a/MAC_SDK/Source/MACLib/NNFilter.cpp b/MAC_SDK/Source/MACLib/NNFilter.cpp deleted file mode 100644 index 0bddc39..0000000 --- a/MAC_SDK/Source/MACLib/NNFilter.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include "All.h" -#include "GlobalFunctions.h" -#include "NNFilter.h" -#include "Assembly/Assembly.h" - -CNNFilter::CNNFilter(int nOrder, int nShift, int nVersion) -{ - if ((nOrder <= 0) || ((nOrder % 16) != 0)) throw(1); - m_nOrder = nOrder; - m_nShift = nShift; - m_nVersion = nVersion; - - m_bMMXAvailable = GetMMXAvailable(); - - m_rbInput.Create(NN_WINDOW_ELEMENTS, m_nOrder); - m_rbDeltaM.Create(NN_WINDOW_ELEMENTS, m_nOrder); - m_paryM = new short [m_nOrder]; - -#ifdef NN_TEST_MMX - srand(GetTickCount()); -#endif -} - -CNNFilter::~CNNFilter() -{ - SAFE_ARRAY_DELETE(m_paryM) -} - -void CNNFilter::Flush() -{ - memset(&m_paryM[0], 0, m_nOrder * sizeof(short)); - m_rbInput.Flush(); - m_rbDeltaM.Flush(); - m_nRunningAverage = 0; -} - -int CNNFilter::Compress(int nInput) -{ - // convert the input to a short and store it - m_rbInput[0] = GetSaturatedShortFromInt(nInput); - - // figure a dot product - int nDotProduct; - if (m_bMMXAvailable) - nDotProduct = CalculateDotProduct(&m_rbInput[-m_nOrder], &m_paryM[0], m_nOrder); - else - nDotProduct = CalculateDotProductNoMMX(&m_rbInput[-m_nOrder], &m_paryM[0], m_nOrder); - - // calculate the output - int nOutput = nInput - ((nDotProduct + (1 << (m_nShift - 1))) >> m_nShift); - - // adapt - if (m_bMMXAvailable) - Adapt(&m_paryM[0], &m_rbDeltaM[-m_nOrder], -nOutput, m_nOrder); - else - AdaptNoMMX(&m_paryM[0], &m_rbDeltaM[-m_nOrder], nOutput, m_nOrder); - - int nTempABS = abs(nInput); - - if (nTempABS > (m_nRunningAverage * 3)) - m_rbDeltaM[0] = ((nInput >> 25) & 64) - 32; - else if (nTempABS > (m_nRunningAverage * 4) / 3) - m_rbDeltaM[0] = ((nInput >> 26) & 32) - 16; - else if (nTempABS > 0) - m_rbDeltaM[0] = ((nInput >> 27) & 16) - 8; - else - m_rbDeltaM[0] = 0; - - m_nRunningAverage += (nTempABS - m_nRunningAverage) / 16; - - m_rbDeltaM[-1] >>= 1; - m_rbDeltaM[-2] >>= 1; - m_rbDeltaM[-8] >>= 1; - - // increment and roll if necessary - m_rbInput.IncrementSafe(); - m_rbDeltaM.IncrementSafe(); - - return nOutput; -} - -int CNNFilter::Decompress(int nInput) -{ - // figure a dot product - int nDotProduct; - - if (m_bMMXAvailable) - { - nDotProduct = CalculateDotProduct(&m_rbInput[-m_nOrder], &m_paryM[0], m_nOrder); - Adapt(&m_paryM[0], &m_rbDeltaM[-m_nOrder], -nInput, m_nOrder); - } - else - { - nDotProduct = CalculateDotProductNoMMX(&m_rbInput[-m_nOrder], &m_paryM[0], m_nOrder); - AdaptNoMMX(&m_paryM[0], &m_rbDeltaM[-m_nOrder], nInput, m_nOrder); - } - - // store the output value - int nOutput = nInput + ((nDotProduct + (1 << (m_nShift - 1))) >> m_nShift); - - // update the input buffer - m_rbInput[0] = GetSaturatedShortFromInt(nOutput); - - if (m_nVersion >= 3980) - { - int nTempABS = abs(nOutput); - - if (nTempABS > (m_nRunningAverage * 3)) - m_rbDeltaM[0] = ((nOutput >> 25) & 64) - 32; - else if (nTempABS > (m_nRunningAverage * 4) / 3) - m_rbDeltaM[0] = ((nOutput >> 26) & 32) - 16; - else if (nTempABS > 0) - m_rbDeltaM[0] = ((nOutput >> 27) & 16) - 8; - else - m_rbDeltaM[0] = 0; - - m_nRunningAverage += (nTempABS - m_nRunningAverage) / 16; - - m_rbDeltaM[-1] >>= 1; - m_rbDeltaM[-2] >>= 1; - m_rbDeltaM[-8] >>= 1; - } - else - { - m_rbDeltaM[0] = (nOutput == 0) ? 0 : ((nOutput >> 28) & 8) - 4; - m_rbDeltaM[-4] >>= 1; - m_rbDeltaM[-8] >>= 1; - } - - // increment and roll if necessary - m_rbInput.IncrementSafe(); - m_rbDeltaM.IncrementSafe(); - - return nOutput; -} - -void CNNFilter::AdaptNoMMX(short * pM, short * pAdapt, int nDirection, int nOrder) -{ - nOrder >>= 4; - - if (nDirection < 0) - { - while (nOrder--) - { - EXPAND_16_TIMES(*pM++ += *pAdapt++;) - } - } - else if (nDirection > 0) - { - while (nOrder--) - { - EXPAND_16_TIMES(*pM++ -= *pAdapt++;) - } - } -} - -int CNNFilter::CalculateDotProductNoMMX(short * pA, short * pB, int nOrder) -{ - int nDotProduct = 0; - nOrder >>= 4; - - while (nOrder--) - { - EXPAND_16_TIMES(nDotProduct += *pA++ * *pB++;) - } - - return nDotProduct; -} diff --git a/MAC_SDK/Source/MACLib/NNFilter.h b/MAC_SDK/Source/MACLib/NNFilter.h deleted file mode 100644 index 0f79aeb..0000000 --- a/MAC_SDK/Source/MACLib/NNFilter.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef APE_NNFILTER_H -#define APE_NNFILTER_H - -#include "RollBuffer.h" -#define NN_WINDOW_ELEMENTS 512 -//#define NN_TEST_MMX - -class CNNFilter -{ -public: - - CNNFilter(int nOrder, int nShift, int nVersion); - ~CNNFilter(); - - int Compress(int nInput); - int Decompress(int nInput); - void Flush(); - -private: - - int m_nOrder; - int m_nShift; - int m_nVersion; - BOOL m_bMMXAvailable; - int m_nRunningAverage; - - CRollBuffer m_rbInput; - CRollBuffer m_rbDeltaM; - - short * m_paryM; -// short * m_paryM_ptr; - - inline short GetSaturatedShortFromInt(int nValue) const - { - return short((nValue == short(nValue)) ? nValue : (nValue >> 31) ^ 0x7FFF); - } - - inline int CalculateDotProductNoMMX(short * pA, short * pB, int nOrder); - inline void AdaptNoMMX(short * pM, short * pAdapt, int nDirection, int nOrder); -}; - -#endif // #ifndef APE_NNFILTER_H diff --git a/MAC_SDK/Source/MACLib/NewPredictor.cpp b/MAC_SDK/Source/MACLib/NewPredictor.cpp deleted file mode 100644 index f9b6e86..0000000 --- a/MAC_SDK/Source/MACLib/NewPredictor.cpp +++ /dev/null @@ -1,408 +0,0 @@ -#include "All.h" -#include "APECompress.h" -#include "NewPredictor.h" - -/***************************************************************************************** -CPredictorCompressNormal -*****************************************************************************************/ -CPredictorCompressNormal::CPredictorCompressNormal(int nCompressionLevel) - : IPredictorCompress(nCompressionLevel) -{ - if (nCompressionLevel == COMPRESSION_LEVEL_FAST) - { - m_pNNFilter = NULL; - m_pNNFilter1 = NULL; - m_pNNFilter2 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_NORMAL) - { - m_pNNFilter = new CNNFilter(16, 11, MAC_VERSION_NUMBER); - m_pNNFilter1 = NULL; - m_pNNFilter2 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_HIGH) - { - m_pNNFilter = new CNNFilter(64, 11, MAC_VERSION_NUMBER); - m_pNNFilter1 = NULL; - m_pNNFilter2 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_EXTRA_HIGH) - { - m_pNNFilter = new CNNFilter(256, 13, MAC_VERSION_NUMBER); - m_pNNFilter1 = new CNNFilter(32, 10, MAC_VERSION_NUMBER); - m_pNNFilter2 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_INSANE) - { - m_pNNFilter = new CNNFilter(1024 + 256, 15, MAC_VERSION_NUMBER); - m_pNNFilter1 = new CNNFilter(256, 13, MAC_VERSION_NUMBER); - m_pNNFilter2 = new CNNFilter(16, 11, MAC_VERSION_NUMBER); - - } - else - { - throw(1); - } -} - -CPredictorCompressNormal::~CPredictorCompressNormal() -{ - SAFE_DELETE(m_pNNFilter) - SAFE_DELETE(m_pNNFilter1) - SAFE_DELETE(m_pNNFilter2) -} - -int CPredictorCompressNormal::Flush() -{ - if (m_pNNFilter) m_pNNFilter->Flush(); - if (m_pNNFilter1) m_pNNFilter1->Flush(); - if (m_pNNFilter2) m_pNNFilter2->Flush(); - - m_rbPrediction.Flush(); - m_rbAdapt.Flush(); - m_Stage1FilterA.Flush(); m_Stage1FilterB.Flush(); - - memset(m_aryM, 0, sizeof(m_aryM)); - - int * paryM = &m_aryM[8]; - paryM[0] = 360; - paryM[-1] = 317; - paryM[-2] = -109; - paryM[-3] = 98; - - m_nCurrentIndex = 0; - - return ERROR_SUCCESS; -} - -int CPredictorCompressNormal::CompressValue(int nA, int nB) -{ - // roll the buffers if necessary - if (m_nCurrentIndex == WINDOW_BLOCKS) - { - m_rbPrediction.Roll(); m_rbAdapt.Roll(); - m_nCurrentIndex = 0; - } - - // stage 1: simple, non-adaptive order 1 prediction - nA = m_Stage1FilterA.Compress(nA); - nB = m_Stage1FilterB.Compress(nB); - - // stage 2: adaptive offset filter(s) - m_rbPrediction[0] = nA; - m_rbPrediction[-2] = m_rbPrediction[-1] - m_rbPrediction[-2]; - - m_rbPrediction[-5] = nB; - m_rbPrediction[-6] = m_rbPrediction[-5] - m_rbPrediction[-6]; - - int * paryM = &m_aryM[8]; - - int nPredictionA = (m_rbPrediction[-1] * paryM[0]) + (m_rbPrediction[-2] * paryM[-1]) + (m_rbPrediction[-3] * paryM[-2]) + (m_rbPrediction[-4] * paryM[-3]); - int nPredictionB = (m_rbPrediction[-5] * paryM[-4]) + (m_rbPrediction[-6] * paryM[-5]) + (m_rbPrediction[-7] * paryM[-6]) + (m_rbPrediction[-8] * paryM[-7]) + (m_rbPrediction[-9] * paryM[-8]); - - int nOutput = nA - ((nPredictionA + (nPredictionB >> 1)) >> 10); - - // adapt - m_rbAdapt[0] = (m_rbPrediction[-1]) ? ((m_rbPrediction[-1] >> 30) & 2) - 1 : 0; - m_rbAdapt[-1] = (m_rbPrediction[-2]) ? ((m_rbPrediction[-2] >> 30) & 2) - 1 : 0; - m_rbAdapt[-4] = (m_rbPrediction[-5]) ? ((m_rbPrediction[-5] >> 30) & 2) - 1 : 0; - m_rbAdapt[-5] = (m_rbPrediction[-6]) ? ((m_rbPrediction[-6] >> 30) & 2) - 1 : 0; - - if (nOutput > 0) - { - int * pM = &paryM[-8]; int * pAdapt = &m_rbAdapt[-8]; - EXPAND_9_TIMES(*pM++ -= *pAdapt++;) - } - else if (nOutput < 0) - { - int * pM = &paryM[-8]; int * pAdapt = &m_rbAdapt[-8]; - EXPAND_9_TIMES(*pM++ += *pAdapt++;) - } - - // stage 3: NNFilters - if (m_pNNFilter) - { - nOutput = m_pNNFilter->Compress(nOutput); - - if (m_pNNFilter1) - { - nOutput = m_pNNFilter1->Compress(nOutput); - - if (m_pNNFilter2) - nOutput = m_pNNFilter2->Compress(nOutput); - } - } - - m_rbPrediction.IncrementFast(); m_rbAdapt.IncrementFast(); - m_nCurrentIndex++; - - return nOutput; -} - -/***************************************************************************************** -CPredictorDecompressNormal3930to3950 -*****************************************************************************************/ -CPredictorDecompressNormal3930to3950::CPredictorDecompressNormal3930to3950(int nCompressionLevel, int nVersion) - : IPredictorDecompress(nCompressionLevel, nVersion) -{ - m_pBuffer[0] = new int [HISTORY_ELEMENTS + WINDOW_BLOCKS]; - - if (nCompressionLevel == COMPRESSION_LEVEL_FAST) - { - m_pNNFilter = NULL; - m_pNNFilter1 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_NORMAL) - { - m_pNNFilter = new CNNFilter(16, 11, nVersion); - m_pNNFilter1 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_HIGH) - { - m_pNNFilter = new CNNFilter(64, 11, nVersion); - m_pNNFilter1 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_EXTRA_HIGH) - { - m_pNNFilter = new CNNFilter(256, 13, nVersion); - m_pNNFilter1 = new CNNFilter(32, 10, nVersion); - } - else - { - throw(1); - } -} - -CPredictorDecompressNormal3930to3950::~CPredictorDecompressNormal3930to3950() -{ - SAFE_DELETE(m_pNNFilter) - SAFE_DELETE(m_pNNFilter1) - SAFE_ARRAY_DELETE(m_pBuffer[0]) -} - -int CPredictorDecompressNormal3930to3950::Flush() -{ - if (m_pNNFilter) m_pNNFilter->Flush(); - if (m_pNNFilter1) m_pNNFilter1->Flush(); - - ZeroMemory(m_pBuffer[0], (HISTORY_ELEMENTS + 1) * sizeof(int)); - ZeroMemory(&m_aryM[0], M_COUNT * sizeof(int)); - - m_aryM[0] = 360; - m_aryM[1] = 317; - m_aryM[2] = -109; - m_aryM[3] = 98; - - m_pInputBuffer = &m_pBuffer[0][HISTORY_ELEMENTS]; - - m_nLastValue = 0; - m_nCurrentIndex = 0; - - return ERROR_SUCCESS; -} - -int CPredictorDecompressNormal3930to3950::DecompressValue(int nInput, int) -{ - if (m_nCurrentIndex == WINDOW_BLOCKS) - { - // copy forward and adjust pointers - memcpy(&m_pBuffer[0][0], &m_pBuffer[0][WINDOW_BLOCKS], HISTORY_ELEMENTS * sizeof(int)); - m_pInputBuffer = &m_pBuffer[0][HISTORY_ELEMENTS]; - - m_nCurrentIndex = 0; - } - - // stage 2: NNFilter - if (m_pNNFilter1) - nInput = m_pNNFilter1->Decompress(nInput); - if (m_pNNFilter) - nInput = m_pNNFilter->Decompress(nInput); - - // stage 1: multiple predictors (order 2 and offset 1) - - int p1 = m_pInputBuffer[-1]; - int p2 = m_pInputBuffer[-1] - m_pInputBuffer[-2]; - int p3 = m_pInputBuffer[-2] - m_pInputBuffer[-3]; - int p4 = m_pInputBuffer[-3] - m_pInputBuffer[-4]; - - m_pInputBuffer[0] = nInput + (((p1 * m_aryM[0]) + (p2 * m_aryM[1]) + (p3 * m_aryM[2]) + (p4 * m_aryM[3])) >> 9); - - if (nInput > 0) - { - m_aryM[0] -= ((p1 >> 30) & 2) - 1; - m_aryM[1] -= ((p2 >> 30) & 2) - 1; - m_aryM[2] -= ((p3 >> 30) & 2) - 1; - m_aryM[3] -= ((p4 >> 30) & 2) - 1; - } - else if (nInput < 0) - { - m_aryM[0] += ((p1 >> 30) & 2) - 1; - m_aryM[1] += ((p2 >> 30) & 2) - 1; - m_aryM[2] += ((p3 >> 30) & 2) - 1; - m_aryM[3] += ((p4 >> 30) & 2) - 1; - } - - int nRetVal = m_pInputBuffer[0] + ((m_nLastValue * 31) >> 5); - m_nLastValue = nRetVal; - - m_nCurrentIndex++; - m_pInputBuffer++; - - return nRetVal; -} - -/***************************************************************************************** -CPredictorDecompress3950toCurrent -*****************************************************************************************/ -CPredictorDecompress3950toCurrent::CPredictorDecompress3950toCurrent(int nCompressionLevel, int nVersion) - : IPredictorDecompress(nCompressionLevel, nVersion) -{ - m_nVersion = nVersion; - - if (nCompressionLevel == COMPRESSION_LEVEL_FAST) - { - m_pNNFilter = NULL; - m_pNNFilter1 = NULL; - m_pNNFilter2 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_NORMAL) - { - m_pNNFilter = new CNNFilter(16, 11, nVersion); - m_pNNFilter1 = NULL; - m_pNNFilter2 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_HIGH) - { - m_pNNFilter = new CNNFilter(64, 11, nVersion); - m_pNNFilter1 = NULL; - m_pNNFilter2 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_EXTRA_HIGH) - { - m_pNNFilter = new CNNFilter(256, 13, nVersion); - m_pNNFilter1 = new CNNFilter(32, 10, nVersion); - m_pNNFilter2 = NULL; - } - else if (nCompressionLevel == COMPRESSION_LEVEL_INSANE) - { - m_pNNFilter = new CNNFilter(1024 + 256, 15, MAC_VERSION_NUMBER); - m_pNNFilter1 = new CNNFilter(256, 13, MAC_VERSION_NUMBER); - m_pNNFilter2 = new CNNFilter(16, 11, MAC_VERSION_NUMBER); - - } - else - { - throw(1); - } -} - -CPredictorDecompress3950toCurrent::~CPredictorDecompress3950toCurrent() -{ - SAFE_DELETE(m_pNNFilter) - SAFE_DELETE(m_pNNFilter1) - SAFE_DELETE(m_pNNFilter2) -} - -int CPredictorDecompress3950toCurrent::Flush() -{ - if (m_pNNFilter) m_pNNFilter->Flush(); - if (m_pNNFilter1) m_pNNFilter1->Flush(); - if (m_pNNFilter2) m_pNNFilter2->Flush(); - - ZeroMemory(m_aryMA, sizeof(m_aryMA)); - ZeroMemory(m_aryMB, sizeof(m_aryMB)); - - m_rbPredictionA.Flush(); - m_rbPredictionB.Flush(); - m_rbAdaptA.Flush(); - m_rbAdaptB.Flush(); - - m_aryMA[0] = 360; - m_aryMA[1] = 317; - m_aryMA[2] = -109; - m_aryMA[3] = 98; - - m_Stage1FilterA.Flush(); - m_Stage1FilterB.Flush(); - - m_nLastValueA = 0; - - m_nCurrentIndex = 0; - - return ERROR_SUCCESS; -} - -int CPredictorDecompress3950toCurrent::DecompressValue(int nA, int nB) -{ - if (m_nCurrentIndex == WINDOW_BLOCKS) - { - // copy forward and adjust pointers - m_rbPredictionA.Roll(); m_rbPredictionB.Roll(); - m_rbAdaptA.Roll(); m_rbAdaptB.Roll(); - - m_nCurrentIndex = 0; - } - - // stage 2: NNFilter - if (m_pNNFilter2) - nA = m_pNNFilter2->Decompress(nA); - if (m_pNNFilter1) - nA = m_pNNFilter1->Decompress(nA); - if (m_pNNFilter) - nA = m_pNNFilter->Decompress(nA); - - // stage 1: multiple predictors (order 2 and offset 1) - m_rbPredictionA[0] = m_nLastValueA; - m_rbPredictionA[-1] = m_rbPredictionA[0] - m_rbPredictionA[-1]; - - m_rbPredictionB[0] = m_Stage1FilterB.Compress(nB); - m_rbPredictionB[-1] = m_rbPredictionB[0] - m_rbPredictionB[-1]; - - int nPredictionA = (m_rbPredictionA[0] * m_aryMA[0]) + (m_rbPredictionA[-1] * m_aryMA[1]) + (m_rbPredictionA[-2] * m_aryMA[2]) + (m_rbPredictionA[-3] * m_aryMA[3]); - int nPredictionB = (m_rbPredictionB[0] * m_aryMB[0]) + (m_rbPredictionB[-1] * m_aryMB[1]) + (m_rbPredictionB[-2] * m_aryMB[2]) + (m_rbPredictionB[-3] * m_aryMB[3]) + (m_rbPredictionB[-4] * m_aryMB[4]); - - int nCurrentA = nA + ((nPredictionA + (nPredictionB >> 1)) >> 10); - - m_rbAdaptA[0] = (m_rbPredictionA[0]) ? ((m_rbPredictionA[0] >> 30) & 2) - 1 : 0; - m_rbAdaptA[-1] = (m_rbPredictionA[-1]) ? ((m_rbPredictionA[-1] >> 30) & 2) - 1 : 0; - - m_rbAdaptB[0] = (m_rbPredictionB[0]) ? ((m_rbPredictionB[0] >> 30) & 2) - 1 : 0; - m_rbAdaptB[-1] = (m_rbPredictionB[-1]) ? ((m_rbPredictionB[-1] >> 30) & 2) - 1 : 0; - - if (nA > 0) - { - m_aryMA[0] -= m_rbAdaptA[0]; - m_aryMA[1] -= m_rbAdaptA[-1]; - m_aryMA[2] -= m_rbAdaptA[-2]; - m_aryMA[3] -= m_rbAdaptA[-3]; - - m_aryMB[0] -= m_rbAdaptB[0]; - m_aryMB[1] -= m_rbAdaptB[-1]; - m_aryMB[2] -= m_rbAdaptB[-2]; - m_aryMB[3] -= m_rbAdaptB[-3]; - m_aryMB[4] -= m_rbAdaptB[-4]; - } - else if (nA < 0) - { - m_aryMA[0] += m_rbAdaptA[0]; - m_aryMA[1] += m_rbAdaptA[-1]; - m_aryMA[2] += m_rbAdaptA[-2]; - m_aryMA[3] += m_rbAdaptA[-3]; - - m_aryMB[0] += m_rbAdaptB[0]; - m_aryMB[1] += m_rbAdaptB[-1]; - m_aryMB[2] += m_rbAdaptB[-2]; - m_aryMB[3] += m_rbAdaptB[-3]; - m_aryMB[4] += m_rbAdaptB[-4]; - } - - int nRetVal = m_Stage1FilterA.Decompress(nCurrentA); - m_nLastValueA = nCurrentA; - - m_rbPredictionA.IncrementFast(); m_rbPredictionB.IncrementFast(); - m_rbAdaptA.IncrementFast(); m_rbAdaptB.IncrementFast(); - - m_nCurrentIndex++; - - return nRetVal; -} diff --git a/MAC_SDK/Source/MACLib/NewPredictor.h b/MAC_SDK/Source/MACLib/NewPredictor.h deleted file mode 100644 index eedb28e..0000000 --- a/MAC_SDK/Source/MACLib/NewPredictor.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef APE_NEWPREDICTOR_H -#define APE_NEWPREDICTOR_H - -#include "Predictor.h" - -#include "RollBuffer.h" -#include "NNFilter.h" -#include "ScaledFirstOrderFilter.h" - -/************************************************************************************************* -Functions to create the interfaces -*************************************************************************************************/ -IPredictorCompress * __stdcall CreateIPredictorCompress(); -IPredictorDecompress * __stdcall CreateIPredictorDecompress(); - -#define WINDOW_BLOCKS 512 - -#define BUFFER_COUNT 1 -#define HISTORY_ELEMENTS 8 -#define M_COUNT 8 - -class CPredictorCompressNormal : public IPredictorCompress -{ -public: - CPredictorCompressNormal(int nCompressionLevel); - virtual ~CPredictorCompressNormal(); - - int CompressValue(int nA, int nB = 0); - int Flush(); - -protected: - - // buffer information - CRollBufferFast m_rbPrediction; - CRollBufferFast m_rbAdapt; - - CScaledFirstOrderFilter<31, 5> m_Stage1FilterA; - CScaledFirstOrderFilter<31, 5> m_Stage1FilterB; - - // adaption - int m_aryM[9]; - - // other - int m_nCurrentIndex; - CNNFilter * m_pNNFilter; - CNNFilter * m_pNNFilter1; - CNNFilter * m_pNNFilter2; -}; - -class CPredictorDecompressNormal3930to3950 : public IPredictorDecompress -{ -public: - CPredictorDecompressNormal3930to3950(int nCompressionLevel, int nVersion); - virtual ~CPredictorDecompressNormal3930to3950(); - - int DecompressValue(int nInput, int); - int Flush(); - -protected: - - // buffer information - int * m_pBuffer[BUFFER_COUNT]; - - // adaption - int m_aryM[M_COUNT]; - - // buffer pointers - int * m_pInputBuffer; - - // other - int m_nCurrentIndex; - int m_nLastValue; - CNNFilter * m_pNNFilter; - CNNFilter * m_pNNFilter1; -}; - -class CPredictorDecompress3950toCurrent : public IPredictorDecompress -{ -public: - CPredictorDecompress3950toCurrent(int nCompressionLevel, int nVersion); - virtual ~CPredictorDecompress3950toCurrent(); - - int DecompressValue(int nA, int nB = 0); - int Flush(); - -protected: - - // adaption - int m_aryMA[M_COUNT]; - int m_aryMB[M_COUNT]; - - // buffer pointers - CRollBufferFast m_rbPredictionA; - CRollBufferFast m_rbPredictionB; - - CRollBufferFast m_rbAdaptA; - CRollBufferFast m_rbAdaptB; - - CScaledFirstOrderFilter<31, 5> m_Stage1FilterA; - CScaledFirstOrderFilter<31, 5> m_Stage1FilterB; - - // other - int m_nCurrentIndex; - int m_nLastValueA; - int m_nVersion; - CNNFilter * m_pNNFilter; - CNNFilter * m_pNNFilter1; - CNNFilter * m_pNNFilter2; -}; - -#endif // #ifndef APE_NEWPREDICTOR_H diff --git a/MAC_SDK/Source/MACLib/Old/APEDecompressCore.cpp b/MAC_SDK/Source/MACLib/Old/APEDecompressCore.cpp deleted file mode 100644 index 84ad6a1..0000000 --- a/MAC_SDK/Source/MACLib/Old/APEDecompressCore.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include "All.h" -#ifdef BACKWARDS_COMPATIBILITY - -#include "UnMAC.h" -#include "APEDecompressCore.h" -#include "../APEInfo.h" -#include "GlobalFunctions.h" -#include "../UnBitArrayBase.h" -#include "Anti-Predictor.h" -#include "UnMAC.h" -#include "../Prepare.h" -#include "../UnBitArray.h" -#include "../Assembly/Assembly.h" - -CAPEDecompressCore::CAPEDecompressCore(CIO * pIO, IAPEDecompress * pAPEDecompress) -{ - m_pAPEDecompress = pAPEDecompress; - - // initialize the bit array - m_pUnBitArray = CreateUnBitArray(pAPEDecompress, pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION)); - - if (m_pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION) >= 3930) - throw(0); - - m_pAntiPredictorX = CreateAntiPredictor(pAPEDecompress->GetInfo(APE_INFO_COMPRESSION_LEVEL), pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION)); - m_pAntiPredictorY = CreateAntiPredictor(pAPEDecompress->GetInfo(APE_INFO_COMPRESSION_LEVEL), pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION)); - - m_pDataX = new int [pAPEDecompress->GetInfo(APE_INFO_BLOCKS_PER_FRAME) + 16]; - m_pDataY = new int [pAPEDecompress->GetInfo(APE_INFO_BLOCKS_PER_FRAME) + 16]; - m_pTempData = new int [pAPEDecompress->GetInfo(APE_INFO_BLOCKS_PER_FRAME) + 16]; - - m_nBlocksProcessed = 0; - - // check to see if MMX is available - m_bMMXAvailable = GetMMXAvailable(); -} - -CAPEDecompressCore::~CAPEDecompressCore() -{ - SAFE_DELETE(m_pUnBitArray) - - SAFE_DELETE(m_pAntiPredictorX) - SAFE_DELETE(m_pAntiPredictorY) - - SAFE_ARRAY_DELETE(m_pDataX) - SAFE_ARRAY_DELETE(m_pDataY) - SAFE_ARRAY_DELETE(m_pTempData) -} - -void CAPEDecompressCore::GenerateDecodedArrays(int nBlocks, int nSpecialCodes, int nFrameIndex, int nCPULoadBalancingFactor) -{ - CUnBitArray * pBitArray = (CUnBitArray *) m_pUnBitArray; - - if (m_pAPEDecompress->GetInfo(APE_INFO_CHANNELS) == 2) - { - if ((nSpecialCodes & SPECIAL_FRAME_LEFT_SILENCE) && (nSpecialCodes & SPECIAL_FRAME_RIGHT_SILENCE)) - { - memset(m_pDataX, 0, nBlocks * 4); - memset(m_pDataY, 0, nBlocks * 4); - } - else if (nSpecialCodes & SPECIAL_FRAME_PSEUDO_STEREO) - { - GenerateDecodedArray(m_pDataX, nBlocks, nFrameIndex, m_pAntiPredictorX, nCPULoadBalancingFactor); - memset(m_pDataY, 0, nBlocks * 4); - } - else - { - GenerateDecodedArray(m_pDataX, nBlocks, nFrameIndex, m_pAntiPredictorX, nCPULoadBalancingFactor); - GenerateDecodedArray(m_pDataY, nBlocks, nFrameIndex, m_pAntiPredictorY, nCPULoadBalancingFactor); - } - } - else - { - if (nSpecialCodes & SPECIAL_FRAME_LEFT_SILENCE) - { - memset(m_pDataX, 0, nBlocks * 4); - } - else - { - GenerateDecodedArray(m_pDataX, nBlocks, nFrameIndex, m_pAntiPredictorX, nCPULoadBalancingFactor); - } - } -} - - -void CAPEDecompressCore::GenerateDecodedArray(int * Input_Array, uint32 Number_of_Elements, int Frame_Index, CAntiPredictor *pAntiPredictor, int CPULoadBalancingFactor) -{ - const int nFrameBytes = m_pAPEDecompress->GetInfo(APE_INFO_FRAME_BYTES, Frame_Index); - - // run the prediction sequence - switch (m_pAPEDecompress->GetInfo(APE_INFO_COMPRESSION_LEVEL)) - { - -#ifdef ENABLE_COMPRESSION_MODE_FAST - case COMPRESSION_LEVEL_FAST: - if (m_pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION) < 3320) - { - m_pUnBitArray->GenerateArray(m_pTempData, Number_of_Elements, nFrameBytes); - pAntiPredictor->AntiPredict(m_pTempData, Input_Array, Number_of_Elements); - } - else - { - m_pUnBitArray->GenerateArray(Input_Array, Number_of_Elements, nFrameBytes); - pAntiPredictor->AntiPredict(Input_Array, NULL, Number_of_Elements); - } - - break; -#endif // #ifdef ENABLE_COMPRESSION_MODE_FAST - -#ifdef ENABLE_COMPRESSION_MODE_NORMAL - - case COMPRESSION_LEVEL_NORMAL: - { - // get the array from the bitstream - m_pUnBitArray->GenerateArray(m_pTempData, Number_of_Elements, nFrameBytes); - pAntiPredictor->AntiPredict(m_pTempData, Input_Array, Number_of_Elements); - break; - } - -#endif // #ifdef ENABLE_COMPRESSION_MODE_NORMAL - -#ifdef ENABLE_COMPRESSION_MODE_HIGH - case COMPRESSION_LEVEL_HIGH: - // get the array from the bitstream - m_pUnBitArray->GenerateArray(m_pTempData, Number_of_Elements, nFrameBytes); - pAntiPredictor->AntiPredict(m_pTempData, Input_Array, Number_of_Elements); - break; -#endif // #ifdef ENABLE_COMPRESSION_MODE_HIGH - -#ifdef ENABLE_COMPRESSION_MODE_EXTRA_HIGH - case COMPRESSION_LEVEL_EXTRA_HIGH: - - unsigned int aryCoefficientsA[64], aryCoefficientsB[64], nNumberOfCoefficients; - - #define GET_COEFFICIENTS(NumberOfCoefficientsBits, ValueBits) \ - nNumberOfCoefficients = m_pUnBitArray->DecodeValue(DECODE_VALUE_METHOD_X_BITS, NumberOfCoefficientsBits); \ - for (unsigned int z = 0; z <= nNumberOfCoefficients; z++) \ - { \ - aryCoefficientsA[z] = m_pUnBitArray->DecodeValue(DECODE_VALUE_METHOD_X_BITS, ValueBits); \ - aryCoefficientsB[z] = m_pUnBitArray->DecodeValue(DECODE_VALUE_METHOD_X_BITS, ValueBits); \ - } \ - - if (m_pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION) < 3320) - { - GET_COEFFICIENTS(4, 6) - m_pUnBitArray->GenerateArray(m_pTempData, Number_of_Elements, nFrameBytes); - ((CAntiPredictorExtraHigh0000To3320 *) pAntiPredictor)->AntiPredict(m_pTempData, Input_Array, Number_of_Elements, nNumberOfCoefficients, &aryCoefficientsA[0], &aryCoefficientsB[0]); - } - else if (m_pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION) < 3600) - { - GET_COEFFICIENTS(3, 5) - m_pUnBitArray->GenerateArray(m_pTempData, Number_of_Elements, nFrameBytes); - ((CAntiPredictorExtraHigh3320To3600 *) pAntiPredictor)->AntiPredict(m_pTempData, Input_Array, Number_of_Elements, nNumberOfCoefficients, &aryCoefficientsA[0], &aryCoefficientsB[0]); - } - else if (m_pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION) < 3700) - { - GET_COEFFICIENTS(3, 6) - m_pUnBitArray->GenerateArray(m_pTempData, Number_of_Elements, nFrameBytes); - ((CAntiPredictorExtraHigh3600To3700 *) pAntiPredictor)->AntiPredict(m_pTempData, Input_Array, Number_of_Elements, nNumberOfCoefficients, &aryCoefficientsA[0], &aryCoefficientsB[0]); - } - else if (m_pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION) < 3800) - { - GET_COEFFICIENTS(3, 6) - m_pUnBitArray->GenerateArray(m_pTempData, Number_of_Elements, nFrameBytes); - ((CAntiPredictorExtraHigh3700To3800 *) pAntiPredictor)->AntiPredict(m_pTempData, Input_Array, Number_of_Elements, nNumberOfCoefficients, &aryCoefficientsA[0], &aryCoefficientsB[0]); - } - else - { - m_pUnBitArray->GenerateArray(m_pTempData, Number_of_Elements, nFrameBytes); - ((CAntiPredictorExtraHigh3800ToCurrent *) pAntiPredictor)->AntiPredict(m_pTempData, Input_Array, Number_of_Elements, m_bMMXAvailable, CPULoadBalancingFactor, m_pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION)); - } - - break; -#endif // #ifdef ENABLE_COMPRESSION_MODE_EXTRA_HIGH - } -} - -#endif // #ifdef BACKWARDS_COMPATIBILITY diff --git a/MAC_SDK/Source/MACLib/Old/APEDecompressCore.h b/MAC_SDK/Source/MACLib/Old/APEDecompressCore.h deleted file mode 100644 index d0b770f..0000000 --- a/MAC_SDK/Source/MACLib/Old/APEDecompressCore.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef APE_DECOMPRESS_CORE_H -#define APE_DECOMPRESS_CORE_H - -class CAPEDecompressCore -{ -public: - - CAPEDecompressCore(CIO * pIO, IAPEDecompress * pAPEDecompress); - ~CAPEDecompressCore(); - - void GenerateDecodedArrays(int nBlocks, int nSpecialCodes, int nFrameIndex, int nCPULoadBalancingFactor); - void GenerateDecodedArray(int *Input_Array, uint32 Number_of_Elements, int Frame_Index, CAntiPredictor *pAntiPredictor, int CPULoadBalancingFactor = 0); - - int * GetDataX() { return m_pDataX; } - int * GetDataY() { return m_pDataY; } - - CUnBitArrayBase * GetUnBitArrray() { return m_pUnBitArray; } - - int * m_pTempData; - int * m_pDataX; - int * m_pDataY; - - CAntiPredictor * m_pAntiPredictorX; - CAntiPredictor * m_pAntiPredictorY; - - CUnBitArrayBase * m_pUnBitArray; - BIT_ARRAY_STATE m_BitArrayStateX; - BIT_ARRAY_STATE m_BitArrayStateY; - - IAPEDecompress * m_pAPEDecompress; - - BOOL m_bMMXAvailable; - int m_nBlocksProcessed; -}; - - -#endif // #ifndef APE_DECOMPRESS_CORE_H \ No newline at end of file diff --git a/MAC_SDK/Source/MACLib/Old/APEDecompressOld.cpp b/MAC_SDK/Source/MACLib/Old/APEDecompressOld.cpp deleted file mode 100644 index 27b3177..0000000 --- a/MAC_SDK/Source/MACLib/Old/APEDecompressOld.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#include "All.h" - -#ifdef BACKWARDS_COMPATIBILITY - -#include "UnMAC.h" -#include "APEDecompressOld.h" -#include "../APEInfo.h" - -CAPEDecompressOld::CAPEDecompressOld(int * pErrorCode, CAPEInfo * pAPEInfo, int nStartBlock, int nFinishBlock) -{ - *pErrorCode = ERROR_SUCCESS; - - // open / analyze the file - m_spAPEInfo.Assign(pAPEInfo); - - // version check (this implementation only works with 3.92 and earlier files) - if (GetInfo(APE_INFO_FILE_VERSION) > 3920) - { - *pErrorCode = ERROR_UNDEFINED; - return; - } - - // create the buffer - m_nBlockAlign = GetInfo(APE_INFO_BLOCK_ALIGN); - - // initialize other stuff - m_nBufferTail = 0; - m_bDecompressorInitialized = FALSE; - m_nCurrentFrame = 0; - m_nCurrentBlock = 0; - - // set the "real" start and finish blocks - m_nStartBlock = (nStartBlock < 0) ? 0 : min(nStartBlock, GetInfo(APE_INFO_TOTAL_BLOCKS)); - m_nFinishBlock = (nFinishBlock < 0) ? GetInfo(APE_INFO_TOTAL_BLOCKS) : min(nFinishBlock, GetInfo(APE_INFO_TOTAL_BLOCKS)); - m_bIsRanged = (m_nStartBlock != 0) || (m_nFinishBlock != GetInfo(APE_INFO_TOTAL_BLOCKS)); -} - -CAPEDecompressOld::~CAPEDecompressOld() -{ - -} - -int CAPEDecompressOld::InitializeDecompressor() -{ - // check if we have anything to do - if (m_bDecompressorInitialized) - return ERROR_SUCCESS; - - // initialize the decoder - RETURN_ON_ERROR(m_UnMAC.Initialize(this)) - - int nMaximumDecompressedFrameBytes = m_nBlockAlign * GetInfo(APE_INFO_BLOCKS_PER_FRAME); - int nTotalBufferBytes = max(65536, (nMaximumDecompressedFrameBytes + 16) * 2); - m_spBuffer.Assign(new char [nTotalBufferBytes], TRUE); - if (m_spBuffer == NULL) - return ERROR_INSUFFICIENT_MEMORY; - - // update the initialized flag - m_bDecompressorInitialized = TRUE; - - // seek to the beginning - return Seek(0); -} - -int CAPEDecompressOld::GetData(char * pBuffer, int nBlocks, int * pBlocksRetrieved) -{ - if (pBlocksRetrieved) *pBlocksRetrieved = 0; - - RETURN_ON_ERROR(InitializeDecompressor()) - - // cap - int nBlocksUntilFinish = m_nFinishBlock - m_nCurrentBlock; - nBlocks = min(nBlocks, nBlocksUntilFinish); - - int nBlocksRetrieved = 0; - - // fulfill as much of the request as possible - int nTotalBytesNeeded = nBlocks * m_nBlockAlign; - int nBytesLeft = nTotalBytesNeeded; - int nBlocksDecoded = 1; - - while (nBytesLeft > 0 && nBlocksDecoded > 0) - { - // empty the buffer - int nBytesAvailable = m_nBufferTail; - int nIntialBytes = min(nBytesLeft, nBytesAvailable); - if (nIntialBytes > 0) - { - memcpy(&pBuffer[nTotalBytesNeeded - nBytesLeft], &m_spBuffer[0], nIntialBytes); - - if ((m_nBufferTail - nIntialBytes) > 0) - memmove(&m_spBuffer[0], &m_spBuffer[nIntialBytes], m_nBufferTail - nIntialBytes); - - nBytesLeft -= nIntialBytes; - m_nBufferTail -= nIntialBytes; - - } - - // decode more - if (nBytesLeft > 0) - { - nBlocksDecoded = m_UnMAC.DecompressFrame((unsigned char *) &m_spBuffer[m_nBufferTail], m_nCurrentFrame++, 0); - if (nBlocksDecoded == -1) - { - return -1; - } - m_nBufferTail += (nBlocksDecoded * m_nBlockAlign); - } - } - - nBlocksRetrieved = (nTotalBytesNeeded - nBytesLeft) / m_nBlockAlign; - - // update the position - m_nCurrentBlock += nBlocksRetrieved; - - if (pBlocksRetrieved) *pBlocksRetrieved = nBlocksRetrieved; - - return ERROR_SUCCESS; -} - -int CAPEDecompressOld::Seek(int nBlockOffset) -{ - RETURN_ON_ERROR(InitializeDecompressor()) - - // use the offset - nBlockOffset += m_nStartBlock; - - // cap (to prevent seeking too far) - if (nBlockOffset >= m_nFinishBlock) - nBlockOffset = m_nFinishBlock - 1; - if (nBlockOffset < m_nStartBlock) - nBlockOffset = m_nStartBlock; - - // flush the buffer - m_nBufferTail = 0; - - // seek to the perfect location - int nBaseFrame = nBlockOffset / GetInfo(APE_INFO_BLOCKS_PER_FRAME); - int nBlocksToSkip = nBlockOffset % GetInfo(APE_INFO_BLOCKS_PER_FRAME); - int nBytesToSkip = nBlocksToSkip * m_nBlockAlign; - - // skip necessary blocks - int nMaximumDecompressedFrameBytes = m_nBlockAlign * GetInfo(APE_INFO_BLOCKS_PER_FRAME); - char *pTempBuffer = new char [nMaximumDecompressedFrameBytes + 16]; - ZeroMemory(pTempBuffer, nMaximumDecompressedFrameBytes + 16); - - m_nCurrentFrame = nBaseFrame; - - int nBlocksDecoded = m_UnMAC.DecompressFrame((unsigned char *) pTempBuffer, m_nCurrentFrame++, 0); - - if (nBlocksDecoded == -1) - { - return -1; - } - - int nBytesToKeep = (nBlocksDecoded * m_nBlockAlign) - nBytesToSkip; - memcpy(&m_spBuffer[m_nBufferTail], &pTempBuffer[nBytesToSkip], nBytesToKeep); - m_nBufferTail += nBytesToKeep; - - delete [] pTempBuffer; - - - m_nCurrentBlock = nBlockOffset; - - return ERROR_SUCCESS; -} - -int CAPEDecompressOld::GetInfo(APE_DECOMPRESS_FIELDS Field, int nParam1, int nParam2) -{ - int nRetVal = 0; - BOOL bHandled = TRUE; - - switch (Field) - { - case APE_DECOMPRESS_CURRENT_BLOCK: - nRetVal = m_nCurrentBlock - m_nStartBlock; - break; - case APE_DECOMPRESS_CURRENT_MS: - { - int nSampleRate = m_spAPEInfo->GetInfo(APE_INFO_SAMPLE_RATE, 0, 0); - if (nSampleRate > 0) - nRetVal = int((double(m_nCurrentBlock) * double(1000)) / double(nSampleRate)); - break; - } - case APE_DECOMPRESS_TOTAL_BLOCKS: - nRetVal = m_nFinishBlock - m_nStartBlock; - break; - case APE_DECOMPRESS_LENGTH_MS: - { - int nSampleRate = m_spAPEInfo->GetInfo(APE_INFO_SAMPLE_RATE, 0, 0); - if (nSampleRate > 0) - nRetVal = int((double(m_nFinishBlock - m_nStartBlock) * double(1000)) / double(nSampleRate)); - break; - } - case APE_DECOMPRESS_CURRENT_BITRATE: - nRetVal = GetInfo(APE_INFO_FRAME_BITRATE, m_nCurrentFrame); - break; - case APE_DECOMPRESS_AVERAGE_BITRATE: - { - if (m_bIsRanged) - { - // figure the frame range - const int nBlocksPerFrame = GetInfo(APE_INFO_BLOCKS_PER_FRAME); - int nStartFrame = m_nStartBlock / nBlocksPerFrame; - int nFinishFrame = (m_nFinishBlock + nBlocksPerFrame - 1) / nBlocksPerFrame; - - // get the number of bytes in the first and last frame - int nTotalBytes = (GetInfo(APE_INFO_FRAME_BYTES, nStartFrame) * (m_nStartBlock % nBlocksPerFrame)) / nBlocksPerFrame; - if (nFinishFrame != nStartFrame) - nTotalBytes += (GetInfo(APE_INFO_FRAME_BYTES, nFinishFrame) * (m_nFinishBlock % nBlocksPerFrame)) / nBlocksPerFrame; - - // get the number of bytes in between - const int nTotalFrames = GetInfo(APE_INFO_TOTAL_FRAMES); - for (int nFrame = nStartFrame + 1; (nFrame < nFinishFrame) && (nFrame < nTotalFrames); nFrame++) - nTotalBytes += GetInfo(APE_INFO_FRAME_BYTES, nFrame); - - // figure the bitrate - int nTotalMS = int((double(m_nFinishBlock - m_nStartBlock) * double(1000)) / double(GetInfo(APE_INFO_SAMPLE_RATE))); - if (nTotalMS != 0) - nRetVal = (nTotalBytes * 8) / nTotalMS; - } - else - { - nRetVal = GetInfo(APE_INFO_AVERAGE_BITRATE); - } - - break; - } - default: - bHandled = FALSE; - } - - if (!bHandled && m_bIsRanged) - { - bHandled = TRUE; - - switch (Field) - { - case APE_INFO_WAV_HEADER_BYTES: - nRetVal = sizeof(WAVE_HEADER); - break; - case APE_INFO_WAV_HEADER_DATA: - { - char * pBuffer = (char *) nParam1; - int nMaxBytes = nParam2; - - if (sizeof(WAVE_HEADER) > nMaxBytes) - { - nRetVal = -1; - } - else - { - WAVEFORMATEX wfeFormat; GetInfo(APE_INFO_WAVEFORMATEX, (int) &wfeFormat, 0); - WAVE_HEADER WAVHeader; FillWaveHeader(&WAVHeader, - (m_nFinishBlock - m_nStartBlock) * GetInfo(APE_INFO_BLOCK_ALIGN), - &wfeFormat, 0); - memcpy(pBuffer, &WAVHeader, sizeof(WAVE_HEADER)); - nRetVal = 0; - } - break; - } - case APE_INFO_WAV_TERMINATING_BYTES: - nRetVal = 0; - break; - case APE_INFO_WAV_TERMINATING_DATA: - nRetVal = 0; - break; - default: - bHandled = FALSE; - } - } - - if (bHandled == FALSE) - nRetVal = m_spAPEInfo->GetInfo(Field, nParam1, nParam2); - - return nRetVal; -} - -#endif // #ifdef BACKWARDS_COMPATIBILITY diff --git a/MAC_SDK/Source/MACLib/Old/APEDecompressOld.h b/MAC_SDK/Source/MACLib/Old/APEDecompressOld.h deleted file mode 100644 index c3b3b61..0000000 --- a/MAC_SDK/Source/MACLib/Old/APEDecompressOld.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _apedecompressold_h_ -#define _apedecompressold_h_ - -#include "../APEDecompress.h" -#include "UnMAC.h" - -class CAPEDecompressOld : public IAPEDecompress -{ -public: - CAPEDecompressOld(int * pErrorCode, CAPEInfo * pAPEInfo, int nStartBlock = -1, int nFinishBlock = -1); - ~CAPEDecompressOld(); - - int GetData(char * pBuffer, int nBlocks, int * pBlocksRetrieved); - int Seek(int nBlockOffset); - - int GetInfo(APE_DECOMPRESS_FIELDS Field, int nParam1 = 0, int nParam2 = 0); - -protected: - - // buffer - CSmartPtr m_spBuffer; - int m_nBufferTail; - - // file info - int m_nBlockAlign; - int m_nCurrentFrame; - - // start / finish information - int m_nStartBlock; - int m_nFinishBlock; - int m_nCurrentBlock; - BOOL m_bIsRanged; - - // decoding tools - CUnMAC m_UnMAC; - CSmartPtr m_spAPEInfo; - - BOOL m_bDecompressorInitialized; - int InitializeDecompressor(); -}; - -#endif //_apedecompressold_h_ - diff --git a/MAC_SDK/Source/MACLib/Old/Anti-Predictor.cpp b/MAC_SDK/Source/MACLib/Old/Anti-Predictor.cpp deleted file mode 100644 index 302e808..0000000 --- a/MAC_SDK/Source/MACLib/Old/Anti-Predictor.cpp +++ /dev/null @@ -1,394 +0,0 @@ -#include "All.h" -#ifdef BACKWARDS_COMPATIBILITY - -#include "../MACLib.h" -#include "Anti-Predictor.h" - -CAntiPredictor * CreateAntiPredictor(int nCompressionLevel, int nVersion) -{ - CAntiPredictor *pAntiPredictor = NULL; - - switch (nCompressionLevel) - { -#ifdef ENABLE_COMPRESSION_MODE_FAST - case COMPRESSION_LEVEL_FAST: - if (nVersion < 3320) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorFast0000To3320; - } - else - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorFast3320ToCurrent; - } - break; -#endif //ENABLE_COMPRESSION_MODE_FAST - -#ifdef ENABLE_COMPRESSION_MODE_NORMAL - - case COMPRESSION_LEVEL_NORMAL: - if (nVersion < 3320) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorNormal0000To3320; - } - else if (nVersion < 3800) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorNormal3320To3800; - } - else - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorNormal3800ToCurrent; - } - break; - -#endif //ENABLE_COMPRESSION_MODE_NORMAL - -#ifdef ENABLE_COMPRESSION_MODE_HIGH - case COMPRESSION_LEVEL_HIGH: - if (nVersion < 3320) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorHigh0000To3320; - } - else if (nVersion < 3600) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorHigh3320To3600; - } - else if (nVersion < 3700) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorHigh3600To3700; - } - else if (nVersion < 3800) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorHigh3700To3800; - } - else - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorHigh3800ToCurrent; - } - break; -#endif //ENABLE_COMPRESSION_MODE_HIGH - -#ifdef ENABLE_COMPRESSION_MODE_EXTRA_HIGH - case COMPRESSION_LEVEL_EXTRA_HIGH: - if (nVersion < 3320) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorExtraHigh0000To3320; - } - else if (nVersion < 3600) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorExtraHigh3320To3600; - } - else if (nVersion < 3700) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorExtraHigh3600To3700; - } - else if (nVersion < 3800) - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorExtraHigh3700To3800; - } - else - { - pAntiPredictor = (CAntiPredictor *) new CAntiPredictorExtraHigh3800ToCurrent; - } - break; -#endif //ENABLE_COMPRESSION_MODE_EXTRA_HIGH - } - - return pAntiPredictor; -} - - - -CAntiPredictor::CAntiPredictor() -{ -} - -CAntiPredictor::~CAntiPredictor() -{ -} - -void CAntiPredictor::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) -{ - return; -} - -void CAntiPredictorOffset::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, int Offset, int DeltaM) -{ - - memcpy(pOutputArray, pInputArray, Offset * 4); - - int *ip = &pInputArray[Offset]; - int *ipo = &pOutputArray[0]; - int *op = &pOutputArray[Offset]; - int m = 0; - - for (; op < &pOutputArray[NumberOfElements]; ip++, ipo++, op++) - { - *op = *ip + ((*ipo * m) >> 12); - - (*ipo ^ *ip) > 0 ? m += DeltaM : m -= DeltaM; - } -} - -#ifdef ENABLE_COMPRESSION_MODE_EXTRA_HIGH - -int CAntiPredictorExtraHighHelper::ConventionalDotProduct(short *bip, short *bbm, short *pIPAdaptFactor, int op, int nNumberOfIterations) -{ - // dot product - int nDotProduct = 0; - short *pMaxBBM = &bbm[nNumberOfIterations]; - - if (op == 0) - { - while(bbm < pMaxBBM) - { - EXPAND_32_TIMES(nDotProduct += *bip++ * *bbm++;) - } - } - else if (op > 0) - { - while(bbm < pMaxBBM) - { - EXPAND_32_TIMES(nDotProduct += *bip++ * *bbm; *bbm++ += *pIPAdaptFactor++;) - } - } - else - { - while(bbm < pMaxBBM) - { - EXPAND_32_TIMES(nDotProduct += *bip++ * *bbm; *bbm++ -= *pIPAdaptFactor++;) - } - } - - // use the dot product - return nDotProduct; -} - -#ifdef ENABLE_ASSEMBLY - -#define MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_HEAD \ - __asm movq mm0, [esi] \ - __asm add esi, 8 \ - __asm movq mm1, [esi] \ - __asm add esi, 8 \ - __asm movq mm2, [esi] \ - __asm add esi, 8 \ - \ - __asm movq mm3, [edi] \ - __asm add edi, 8 \ - __asm movq mm4, [edi] \ - __asm add edi, 8 \ - __asm movq mm5, [edi] \ - __asm sub edi, 16 \ - \ - __asm pmaddwd mm0, mm3 \ - __asm pmaddwd mm1, mm4 \ - __asm pmaddwd mm2, mm5 \ - \ - __asm paddd mm7, mm0 \ - __asm paddd mm7, mm1 \ - __asm paddd mm7, mm2 \ - - -#define MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD \ - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_HEAD \ - \ - __asm paddw mm3, DWORD PTR [eax] \ - __asm movq [edi], mm3 \ - __asm add eax, 8 \ - __asm add edi, 8 \ - __asm paddw mm4, DWORD PTR [eax] \ - __asm movq [edi], mm4 \ - __asm add eax, 8 \ - __asm add edi, 8 \ - __asm paddw mm5, DWORD PTR [eax] \ - __asm movq [edi], mm5 \ - __asm add eax, 8 \ - __asm add edi, 8 - -#define MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT \ - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_HEAD \ - \ - __asm psubw mm3, DWORD PTR [eax] \ - __asm movq [edi], mm3 \ - __asm add eax, 8 \ - __asm add edi, 8 \ - __asm psubw mm4, DWORD PTR [eax] \ - __asm movq [edi], mm4 \ - __asm add eax, 8 \ - __asm add edi, 8 \ - __asm psubw mm5, DWORD PTR [eax] \ - __asm movq [edi], mm5 \ - __asm add eax, 8 \ - __asm add edi, 8 - -int CAntiPredictorExtraHighHelper::MMXDotProduct(short *bip, short *bbm, short *pIPAdaptFactor, int op, int nNumberOfIterations) -{ - int nDotProduct; - nNumberOfIterations = (nNumberOfIterations / 128); - - if (op > 0) - { - __asm - { - push eax - - mov eax, DWORD PTR [pIPAdaptFactor] - - push esi - push edi - - mov esi, DWORD PTR bip[0] - mov edi, DWORD PTR bbm[0] - - pxor mm7, mm7 - -LBL_ADD_AGAIN: - - ///////////////////////////////////////////////////////// - // process 8 mm registers full - ///////////////////////////////////////////////////////// - - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_ADD - - // fill the registers - movq mm0, [esi] - add esi, 8 - movq mm1, [esi] - add esi, 8 - - movq mm3, [edi] - add edi, 8 - movq mm4, [edi] - sub edi, 8 - - pmaddwd mm0, mm3 - pmaddwd mm1, mm4 - - paddd mm7, mm0 - paddd mm7, mm1 - - paddw mm3, DWORD PTR [eax] - movq [edi], mm3 - add eax, 8 - add edi, 8 - paddw mm4, DWORD PTR [eax] - movq [edi], mm4 - add eax, 8 - add edi, 8 - - sub nNumberOfIterations, 1 - cmp nNumberOfIterations, 0 - jg LBL_ADD_AGAIN - - /////////////////////////////////////////////////////////////// - // clean-up - /////////////////////////////////////////////////////////////// - // mm7 has the final dot-product (split into two dwords) - movq mm6, mm7 - psrlq mm7, 32 - paddd mm6, mm7 - movd nDotProduct, mm6 - - pop edi - pop esi - pop eax - emms - - } - } - else - { - __asm - { - push eax - - mov eax, DWORD PTR [pIPAdaptFactor] - - push esi - push edi - - mov esi, DWORD PTR bip[0] - mov edi, DWORD PTR bbm[0] - - pxor mm7, mm7 - -LBL_SUBTRACT_AGAIN: - - ///////////////////////////////////////////////////////// - // process 8 mm registers full - ///////////////////////////////////////////////////////// - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT - MMX_DOT_PRODUCT_3800_TO_CURRENT_PROCESS_CHUNK_SUBTRACT - - // fill the registers - movq mm0, [esi] - add esi, 8 - movq mm1, [esi] - add esi, 8 - - movq mm3, [edi] - add edi, 8 - movq mm4, [edi] - sub edi, 8 - - pmaddwd mm0, mm3 - pmaddwd mm1, mm4 - - paddd mm7, mm0 - paddd mm7, mm1 - - psubw mm3, DWORD PTR [eax] - movq [edi], mm3 - add eax, 8 - add edi, 8 - psubw mm4, DWORD PTR [eax] - movq [edi], mm4 - add eax, 8 - add edi, 8 - - sub nNumberOfIterations, 1 - cmp nNumberOfIterations, 0 - jg LBL_SUBTRACT_AGAIN - - /////////////////////////////////////////////////////////////// - // clean-up - /////////////////////////////////////////////////////////////// - // mm7 has the final dot-product (split into two dwords) - movq mm6, mm7 - psrlq mm7, 32 - paddd mm6, mm7 - movd nDotProduct, mm6 - - pop edi - pop esi - pop eax - emms - - } - } - - return nDotProduct; -} - -#endif // #ifdef ENABLE_ASSEMBLY - -#endif // #ifdef ENABLE_COMPRESSION_MODE_EXTRA_HIGH - -#endif // #ifdef BACKWARDS_COMPATIBILITY diff --git a/MAC_SDK/Source/MACLib/Old/Anti-Predictor.h b/MAC_SDK/Source/MACLib/Old/Anti-Predictor.h deleted file mode 100644 index fc72ac4..0000000 --- a/MAC_SDK/Source/MACLib/Old/Anti-Predictor.h +++ /dev/null @@ -1,253 +0,0 @@ -#ifndef APE_ANTIPREDICTOR_H -#define APE_ANTIPREDICTOR_H - -class CAntiPredictor; - -CAntiPredictor * CreateAntiPredictor(int nCompressionLevel, int nVersion); - -/***************************************************************************************** -Base class for all anti-predictors -*****************************************************************************************/ -class CAntiPredictor -{ -public: - - // construction/destruction - CAntiPredictor(); - ~CAntiPredictor(); - - // functions - virtual void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -/***************************************************************************************** -Offset anti-predictor -*****************************************************************************************/ -class CAntiPredictorOffset : public CAntiPredictor -{ -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, int Offset, int DeltaM); -}; - -#ifdef ENABLE_COMPRESSION_MODE_FAST - -/***************************************************************************************** -Fast anti-predictor (from original 'fast' mode...updated for version 3.32) -*****************************************************************************************/ -class CAntiPredictorFast0000To3320 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -/***************************************************************************************** -Fast anti-predictor (new 'fast' mode release with version 3.32) -*****************************************************************************************/ -class CAntiPredictorFast3320ToCurrent : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -#endif // #ifdef ENABLE_COMPRESSION_MODE_FAST - -#ifdef ENABLE_COMPRESSION_MODE_NORMAL -/***************************************************************************************** -Normal anti-predictor -*****************************************************************************************/ -class CAntiPredictorNormal0000To3320 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -/***************************************************************************************** -Normal anti-predictor -*****************************************************************************************/ -class CAntiPredictorNormal3320To3800 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -/***************************************************************************************** -Normal anti-predictor -*****************************************************************************************/ -class CAntiPredictorNormal3800ToCurrent : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -#endif // #ifdef ENABLE_COMPRESSION_MODE_NORMAL - -#ifdef ENABLE_COMPRESSION_MODE_HIGH - -/***************************************************************************************** -High anti-predictor -*****************************************************************************************/ -class CAntiPredictorHigh0000To3320 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -/***************************************************************************************** -High anti-predictor -*****************************************************************************************/ -class CAntiPredictorHigh3320To3600 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -/***************************************************************************************** -High anti-predictor -*****************************************************************************************/ -class CAntiPredictorHigh3600To3700 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -/***************************************************************************************** -High anti-predictor -*****************************************************************************************/ -class CAntiPredictorHigh3700To3800 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -/***************************************************************************************** -High anti-predictor -*****************************************************************************************/ -class CAntiPredictorHigh3800ToCurrent : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements); - -}; - -#endif // #ifdef ENABLE_COMPRESSION_MODE_HIGH - -#ifdef ENABLE_COMPRESSION_MODE_EXTRA_HIGH - -/***************************************************************************************** -Extra high helper -*****************************************************************************************/ -class CAntiPredictorExtraHighHelper -{ -public: - int ConventionalDotProduct(short *bip, short *bbm, short *pIPAdaptFactor, int op, int nNumberOfIterations); - -#ifdef ENABLE_ASSEMBLY - int MMXDotProduct(short *bip, short *bbm, short *pIPAdaptFactor, int op, int nNumberOfIterations); -#endif // #ifdef ENABLE_ASSEMBLY -}; - - -/***************************************************************************************** -Extra high anti-predictor -*****************************************************************************************/ -class CAntiPredictorExtraHigh0000To3320 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, int Iterations, unsigned int *pOffsetValueArrayA, unsigned int *pOffsetValueArrayB); - -private: - void AntiPredictorOffset(int* Input_Array, int* Output_Array, int Number_of_Elements, int g, int dm, int Max_Order); - -}; - -/***************************************************************************************** -Extra high anti-predictor -*****************************************************************************************/ -class CAntiPredictorExtraHigh3320To3600 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, int Iterations, unsigned int *pOffsetValueArrayA, unsigned int *pOffsetValueArrayB); - -private: - void AntiPredictorOffset(int* Input_Array, int* Output_Array, int Number_of_Elements, int g, int dm, int Max_Order); -}; - -/***************************************************************************************** -Extra high anti-predictor -*****************************************************************************************/ -class CAntiPredictorExtraHigh3600To3700 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, int Iterations, unsigned int *pOffsetValueArrayA, unsigned int *pOffsetValueArrayB); - -private: - void AntiPredictorOffset(int* Input_Array, int* Output_Array, int Number_of_Elements, int g1, int g2, int Max_Order); - -}; - -/***************************************************************************************** -Extra high anti-predictor -*****************************************************************************************/ -class CAntiPredictorExtraHigh3700To3800 : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, int Iterations, unsigned int *pOffsetValueArrayA, unsigned int *pOffsetValueArrayB); - -private: - void AntiPredictorOffset(int* Input_Array, int* Output_Array, int Number_of_Elements, int g1, int g2, int Max_Order); -}; - -/***************************************************************************************** -Extra high anti-predictor -*****************************************************************************************/ -class CAntiPredictorExtraHigh3800ToCurrent : public CAntiPredictor { - -public: - - // functions - void AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, BOOL bMMXAvailable, int CPULoadBalancingFactor, int nVersion); -}; - -#endif // #ifdef ENABLE_COMPRESSION_MODE_EXTRA_HIGH - -#endif // #ifndef APE_ANTIPREDICTOR_H \ No newline at end of file diff --git a/MAC_SDK/Source/MACLib/Old/AntiPredictorExtraHigh.cpp b/MAC_SDK/Source/MACLib/Old/AntiPredictorExtraHigh.cpp deleted file mode 100644 index 7200fae..0000000 --- a/MAC_SDK/Source/MACLib/Old/AntiPredictorExtraHigh.cpp +++ /dev/null @@ -1,330 +0,0 @@ -#include "All.h" -#ifdef BACKWARDS_COMPATIBILITY - -#include "Anti-Predictor.h" - -#ifdef ENABLE_COMPRESSION_MODE_EXTRA_HIGH - -/***************************************************************************************** -Extra high 0000 to 3320 implementation -*****************************************************************************************/ -void CAntiPredictorExtraHigh0000To3320::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, int Iterations, unsigned int *pOffsetValueArrayA, unsigned int *pOffsetValueArrayB) { - for (int z = Iterations; z >= 0; z--){ - AntiPredictorOffset(pInputArray, pOutputArray, NumberOfElements, pOffsetValueArrayB[z], -1, 64); - AntiPredictorOffset(pOutputArray, pInputArray, NumberOfElements, pOffsetValueArrayA[z], 1, 64); - } - - CAntiPredictorHigh0000To3320 AntiPredictor; - AntiPredictor.AntiPredict(pInputArray, pOutputArray, NumberOfElements); -} - -void CAntiPredictorExtraHigh0000To3320::AntiPredictorOffset(int* Input_Array, int* Output_Array, int Number_of_Elements, int g, int dm, int Max_Order) -{ - int q; - - if ((g==0) || (Number_of_Elements <= Max_Order)) { - memcpy(Output_Array, Input_Array, Number_of_Elements * 4); - return; - } - - memcpy(Output_Array, Input_Array, Max_Order * 4); - - int m = 512; - - if (dm > 0) - for (q = Max_Order; q < Number_of_Elements; q++) { - Output_Array[q] = Input_Array[q] + (Output_Array[q - g] >> 3); - } - - else - for (q = Max_Order; q < Number_of_Elements; q++) { - Output_Array[q] = Input_Array[q] - (Output_Array[q - g] >> 3); - } -} - - -/***************************************************************************************** -Extra high 3320 to 3600 implementation -*****************************************************************************************/ -void CAntiPredictorExtraHigh3320To3600::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, int Iterations, unsigned int *pOffsetValueArrayA, unsigned int *pOffsetValueArrayB) -{ - for (int z = Iterations; z >= 0; z--) - { - AntiPredictorOffset(pInputArray, pOutputArray, NumberOfElements, pOffsetValueArrayB[z], -1, 32); - AntiPredictorOffset(pOutputArray, pInputArray, NumberOfElements, pOffsetValueArrayA[z], 1, 32); - } - - CAntiPredictorHigh0000To3320 AntiPredictor; - AntiPredictor.AntiPredict(pInputArray, pOutputArray, NumberOfElements); -} - - -void CAntiPredictorExtraHigh3320To3600::AntiPredictorOffset(int* Input_Array, int* Output_Array, int Number_of_Elements, int g, int dm, int Max_Order) -{ - - int q; - - if ((g==0) || (Number_of_Elements <= Max_Order)) { - memcpy(Output_Array, Input_Array, Number_of_Elements * 4); - return; - } - - memcpy(Output_Array, Input_Array, Max_Order * 4); - - int m = 512; - - if (dm > 0) - for (q = Max_Order; q < Number_of_Elements; q++) { - Output_Array[q] = Input_Array[q] + ((Output_Array[q - g] * m) >> 12); - (Input_Array[q] ^ Output_Array[q - g]) > 0 ? m += 8 : m -= 8; - } - - else - for (q = Max_Order; q < Number_of_Elements; q++) { - Output_Array[q] = Input_Array[q] - ((Output_Array[q - g] * m) >> 12); - (Input_Array[q] ^ Output_Array[q - g]) > 0 ? m -= 8 : m += 8; - } -} - - -/***************************************************************************************** -Extra high 3600 to 3700 implementation -*****************************************************************************************/ -void CAntiPredictorExtraHigh3600To3700::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, int Iterations, unsigned int *pOffsetValueArrayA, unsigned int *pOffsetValueArrayB) { - for (int z = Iterations; z >= 0; ){ - - AntiPredictorOffset(pInputArray, pOutputArray, NumberOfElements, pOffsetValueArrayA[z], pOffsetValueArrayB[z], 64); - z--; - - if (z >= 0) { - AntiPredictorOffset(pOutputArray, pInputArray, NumberOfElements, pOffsetValueArrayA[z], pOffsetValueArrayB[z], 64); - z--; - } - else { - memcpy(pInputArray, pOutputArray, NumberOfElements * 4); - goto Exit_Loop; - z--; - } - } - -Exit_Loop: - CAntiPredictorHigh3600To3700 AntiPredictor; - AntiPredictor.AntiPredict(pInputArray, pOutputArray, NumberOfElements); -} - -void CAntiPredictorExtraHigh3600To3700::AntiPredictorOffset(int* Input_Array, int* Output_Array, int Number_of_Elements, int g1, int g2, int Max_Order) { - int q; - - if ((g1==0) || (g2==0) || (Number_of_Elements <= Max_Order)) { - memcpy(Output_Array, Input_Array, Number_of_Elements * 4); - return; - } - - memcpy(Output_Array, Input_Array, Max_Order * 4); - - int m = 64; - int m2 = 64; - - for (q = Max_Order; q < Number_of_Elements; q++) { - Output_Array[q] = Input_Array[q] + ((Output_Array[q - g1] * m) >> 9) - ((Output_Array[q - g2] * m2) >> 9); - (Input_Array[q] ^ Output_Array[q - g1]) > 0 ? m++ : m--; - (Input_Array[q] ^ Output_Array[q - g2]) > 0 ? m2-- : m2++; - } -} - -/***************************************************************************************** -Extra high 3700 to 3800 implementation -*****************************************************************************************/ -void CAntiPredictorExtraHigh3700To3800::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, int Iterations, unsigned int *pOffsetValueArrayA, unsigned int *pOffsetValueArrayB) { - for (int z = Iterations; z >= 0; ) { - - AntiPredictorOffset(pInputArray, pOutputArray, NumberOfElements, pOffsetValueArrayA[z], pOffsetValueArrayB[z], 64); - z--; - - if (z >= 0) { - AntiPredictorOffset(pOutputArray, pInputArray, NumberOfElements, pOffsetValueArrayA[z], pOffsetValueArrayB[z], 64); - z--; - } - else { - memcpy(pInputArray, pOutputArray, NumberOfElements * 4); - goto Exit_Loop; - z--; - } - } - -Exit_Loop: - CAntiPredictorHigh3700To3800 AntiPredictor; - AntiPredictor.AntiPredict(pInputArray, pOutputArray, NumberOfElements); - -} - -void CAntiPredictorExtraHigh3700To3800::AntiPredictorOffset(int* Input_Array, int* Output_Array, int Number_of_Elements, int g1, int g2, int Max_Order) { - int q; - - if ((g1==0) || (g2==0) || (Number_of_Elements <= Max_Order)) { - memcpy(Output_Array, Input_Array, Number_of_Elements * 4); - return; - } - - memcpy(Output_Array, Input_Array, Max_Order * 4); - - int m = 64; - int m2 = 64; - - for (q = Max_Order; q < Number_of_Elements; q++) { - Output_Array[q] = Input_Array[q] + ((Output_Array[q - g1] * m) >> 9) - ((Output_Array[q - g2] * m2) >> 9); - (Input_Array[q] ^ Output_Array[q - g1]) > 0 ? m++ : m--; - (Input_Array[q] ^ Output_Array[q - g2]) > 0 ? m2-- : m2++; - } -} - -/***************************************************************************************** -Extra high 3800 to Current -*****************************************************************************************/ -void CAntiPredictorExtraHigh3800ToCurrent::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements, BOOL bMMXAvailable, int CPULoadBalancingFactor, int nVersion) -{ - const int nFilterStageElements = (nVersion < 3830) ? 128 : 256; - const int nFilterStageShift = (nVersion < 3830) ? 11 : 12; - const int nMaxElements = (nVersion < 3830) ? 134 : 262; - const int nFirstElement = (nVersion < 3830) ? 128 : 256; - const int nStageCShift = (nVersion < 3830) ? 10 : 11; - - //short frame handling - if (NumberOfElements < nMaxElements) { - memcpy(pOutputArray, pInputArray, NumberOfElements * 4); - return; - } - - //make the first five samples identical in both arrays - memcpy(pOutputArray, pInputArray, nFirstElement * 4); - - //variable declares and initializations - //short bm[nFirstElement]; memset(bm, 0, nFirstElement * 2); - short bm[256]; memset(bm, 0, 256 * 2); - int m2 = 64, m3 = 115, m4 = 64, m5 = 740, m6 = 0; - int p4 = pInputArray[nFirstElement - 1]; - int p3 = (pInputArray[nFirstElement - 1] - pInputArray[nFirstElement - 2]) << 1; - int p2 = pInputArray[nFirstElement - 1] + ((pInputArray[nFirstElement - 3] - pInputArray[nFirstElement - 2]) << 3);// - pInputArray[3] + pInputArray[2]; - int *op = &pOutputArray[nFirstElement]; - int *ip = &pInputArray[nFirstElement]; - int IPP2 = ip[-2]; - int IPP1 = ip[-1]; - int p7 = 2 * ip[-1] - ip[-2]; - int opp = op[-1]; - int Original; - CAntiPredictorExtraHighHelper Helper; - - //undo the initial prediction stuff - int q; // loop variable - for (q = 1; q < nFirstElement; q++) { - pOutputArray[q] += pOutputArray[q - 1]; - } - - //pump the primary loop - short *IPAdaptFactor = (short *) calloc(NumberOfElements, 2); - short *IPShort = (short *) calloc(NumberOfElements, 2); - for (q = 0; q < nFirstElement; q++) { - IPAdaptFactor[q] = ((pInputArray[q] >> 30) & 2) - 1; - IPShort[q] = short(pInputArray[q]); - } - - int FM[9]; memset(&FM[0], 0, 9 * 4); - int FP[9]; memset(&FP[0], 0, 9 * 4); - - for (q = nFirstElement; op < &pOutputArray[NumberOfElements]; op++, ip++, q++) { - //CPU load-balancing - if (CPULoadBalancingFactor > 0) { - if ((q % CPULoadBalancingFactor) == 0) { SLEEP(1); } - } - - if (nVersion >= 3830) - { - int *pFP = &FP[8]; - int *pFM = &FM[8]; - int nDotProduct = 0; - FP[0] = ip[0]; - - if (FP[0] == 0) - { - EXPAND_8_TIMES(nDotProduct += *pFP * *pFM--; *pFP-- = *(pFP - 1);) - } - else if (FP[0] > 0) - { - EXPAND_8_TIMES(nDotProduct += *pFP * *pFM; *pFM-- += ((*pFP >> 30) & 2) - 1; *pFP-- = *(pFP - 1);) - } - else - { - EXPAND_8_TIMES(nDotProduct += *pFP * *pFM; *pFM-- -= ((*pFP >> 30) & 2) - 1; *pFP-- = *(pFP - 1);) - } - - *ip -= nDotProduct >> 9; - } - - Original = *ip; - - IPShort[q] = short(*ip); - IPAdaptFactor[q] = ((ip[0] >> 30) & 2) - 1; - -#ifdef ENABLE_ASSEMBLY - if (bMMXAvailable && (Original != 0)) - { - *ip -= (Helper.MMXDotProduct(&IPShort[q-nFirstElement], &bm[0], &IPAdaptFactor[q-nFirstElement], Original, nFilterStageElements) >> nFilterStageShift); - } - else - { - *ip -= (Helper.ConventionalDotProduct(&IPShort[q-nFirstElement], &bm[0], &IPAdaptFactor[q-nFirstElement], Original, nFilterStageElements) >> nFilterStageShift); - } -#else - *ip -= (Helper.ConventionalDotProduct(&IPShort[q-nFirstElement], &bm[0], &IPAdaptFactor[q-nFirstElement], Original, nFilterStageElements) >> nFilterStageShift); -#endif - - IPShort[q] = short(*ip); - IPAdaptFactor[q] = ((ip[0] >> 30) & 2) - 1; - - ///////////////////////////////////////////// - *op = *ip + (((p2 * m2) + (p3 * m3) + (p4 * m4)) >> 11); - - if (*ip > 0) { - m2 -= ((p2 >> 30) & 2) - 1; - m3 -= ((p3 >> 28) & 8) - 4; - m4 -= ((p4 >> 28) & 8) - 4; - } - else if (*ip < 0) { - m2 += ((p2 >> 30) & 2) - 1; - m3 += ((p3 >> 28) & 8) - 4; - m4 += ((p4 >> 28) & 8) - 4; - } - - - p2 = *op + ((IPP2 - p4) << 3); - p3 = (*op - p4) << 1; - IPP2 = p4; - p4 = *op; - - ///////////////////////////////////////////// - *op += (((p7 * m5) - (opp * m6)) >> nStageCShift); - - if (p4 > 0) { - m5 -= ((p7 >> 29) & 4) - 2; - m6 += ((opp >> 30) & 2) - 1; - } - else if (p4 < 0) { - m5 += ((p7 >> 29) & 4) - 2; - m6 -= ((opp >> 30) & 2) - 1; - } - - p7 = 2 * *op - opp; - opp = *op; - - ///////////////////////////////////////////// - *op += ((op[-1] * 31) >> 5); - - } - - free(IPAdaptFactor); - free(IPShort); -} - -#endif // #ifdef ENABLE_COMPRESSION_MODE_EXTRA_HIGH - -#endif // #ifdef BACKWARDS_COMPATIBILITY diff --git a/MAC_SDK/Source/MACLib/Old/AntiPredictorFast.cpp b/MAC_SDK/Source/MACLib/Old/AntiPredictorFast.cpp deleted file mode 100644 index 2855a3f..0000000 --- a/MAC_SDK/Source/MACLib/Old/AntiPredictorFast.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "All.h" -#ifdef BACKWARDS_COMPATIBILITY - -#include "Anti-Predictor.h" - -#ifdef ENABLE_COMPRESSION_MODE_FAST - -void CAntiPredictorFast0000To3320::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) { - - //short frame handling - if (NumberOfElements < 32) { - memcpy(pOutputArray, pInputArray, NumberOfElements * 4); - return; - } - - //the initial - pOutputArray[0] = pInputArray[0]; - pOutputArray[1] = pInputArray[1] + pOutputArray[0]; - pOutputArray[2] = pInputArray[2] + pOutputArray[1]; - pOutputArray[3] = pInputArray[3] + pOutputArray[2]; - pOutputArray[4] = pInputArray[4] + pOutputArray[3]; - pOutputArray[5] = pInputArray[5] + pOutputArray[4]; - pOutputArray[6] = pInputArray[6] + pOutputArray[5]; - pOutputArray[7] = pInputArray[7] + pOutputArray[6]; - - //the rest - int p, pw; - int m = 4000; - int *ip, *op, *op1; - - op1 = &pOutputArray[7]; - p = (*op1 * 2) - pOutputArray[6]; - pw = (p * m) >> 12; - - for (op = &pOutputArray[8], ip = &pInputArray[8]; ip < &pInputArray[NumberOfElements]; ip++, op++, op1++) { - *op = *ip + pw; - - - //adjust m - if (*ip > 0) - m += (p > 0) ? 4 : -4; - else if (*ip < 0) - m += (p > 0) ? -4 : 4; - - p = (*op * 2) - *op1; - pw = (p * m) >> 12; - - } -} - -///////note: no output - overwrites input///////////////// -void CAntiPredictorFast3320ToCurrent::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) { - - //short frame handling - if (NumberOfElements < 3) { - return; - } - - //variable declares - int p; - int m = 375; - int *ip; - int IP2 = pInputArray[1]; - int IP3 = pInputArray[0]; - int OP1 = pInputArray[1]; - - //the decompression loop (order 2 followed by order 1) - for (ip = &pInputArray[2]; ip < &pInputArray[NumberOfElements]; ip++) { - - //make a prediction for order 2 - p = IP2 + IP2 - IP3; - - //rollback the values - IP3 = IP2; - IP2 = *ip + ((p * m) >> 9); - - //adjust m for the order 2 - (*ip ^ p) > 0 ? m++ : m--; - - //set the output value - *ip = IP2 + OP1; - OP1 = *ip; - } -} - -#endif // #ifdef ENABLE_COMPRESSION_MODE_FAST - -#endif // #ifdef BACKWARDS_COMPATIBILITY diff --git a/MAC_SDK/Source/MACLib/Old/AntiPredictorHigh.cpp b/MAC_SDK/Source/MACLib/Old/AntiPredictorHigh.cpp deleted file mode 100644 index b0cc5a0..0000000 --- a/MAC_SDK/Source/MACLib/Old/AntiPredictorHigh.cpp +++ /dev/null @@ -1,484 +0,0 @@ -#include "All.h" -#ifdef BACKWARDS_COMPATIBILITY - -#include "Anti-Predictor.h" - -#ifdef ENABLE_COMPRESSION_MODE_HIGH - -void CAntiPredictorHigh0000To3320::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) -{ - // variable declares - int p, pw; - int q; - int m; - - // short frame handling - if (NumberOfElements < 32) - { - memcpy(pOutputArray, pInputArray, NumberOfElements * 4); - return; - } - - //////////////////////////////////////// - // order 5 - //////////////////////////////////////// - memcpy(pOutputArray, pInputArray, 32); - - // initialize values - m = 0; - - for (q = 8; q < NumberOfElements; q++) - { - p = (5 * pOutputArray[q - 1]) - (10 * pOutputArray[q - 2]) + (12 * pOutputArray[q - 3]) - (7 * pOutputArray[q - 4]) + pOutputArray[q - 5]; - - pw = (p * m) >> 12; - - pOutputArray[q] = pInputArray[q] + pw; - - // adjust m - if (pInputArray[q] > 0) - (p > 0) ? m += 1 : m -= 1; - else if (pInputArray[q] < 0) - (p > 0) ? m -= 1 : m += 1; - - } - - /////////////////////////////////////// - // order 4 - /////////////////////////////////////// - memcpy(pInputArray, pOutputArray, 32); - m = 0; - - for (q = 8; q < NumberOfElements; q++) - { - p = (4 * pInputArray[q - 1]) - (6 * pInputArray[q - 2]) + (4 * pInputArray[q - 3]) - pInputArray[q - 4]; - pw = (p * m) >> 12; - - pInputArray[q] = pOutputArray[q] + pw; - - // adjust m - if (pOutputArray[q] > 0) - (p > 0) ? m += 2 : m -= 2; - else if (pOutputArray[q] < 0) - (p > 0) ? m -= 2 : m += 2; - } - - CAntiPredictorNormal0000To3320 AntiPredictor; - AntiPredictor.AntiPredict(pInputArray, pOutputArray, NumberOfElements); -} - -void CAntiPredictorHigh3320To3600::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) -{ - // short frame handling - if (NumberOfElements < 8) - { - memcpy(pOutputArray, pInputArray, NumberOfElements * 4); - return; - } - - // do the offset anti-prediction - CAntiPredictorOffset AntiPredictorOffset; - AntiPredictorOffset.AntiPredict(pInputArray, pOutputArray, NumberOfElements, 2, 12); - AntiPredictorOffset.AntiPredict(pOutputArray, pInputArray, NumberOfElements, 3, 12); - - AntiPredictorOffset.AntiPredict(pInputArray, pOutputArray, NumberOfElements, 4, 12); - AntiPredictorOffset.AntiPredict(pOutputArray, pInputArray, NumberOfElements, 5, 12); - - AntiPredictorOffset.AntiPredict(pInputArray, pOutputArray, NumberOfElements, 6, 12); - AntiPredictorOffset.AntiPredict(pOutputArray, pInputArray, NumberOfElements, 7, 12); - - // use the normal mode - CAntiPredictorNormal3320To3800 AntiPredictor; - AntiPredictor.AntiPredict(pInputArray, pOutputArray, NumberOfElements); -} - -void CAntiPredictorHigh3600To3700::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) -{ - // variable declares - int q; - - // short frame handling - if (NumberOfElements < 16) - { - memcpy(pOutputArray, pInputArray, NumberOfElements * 4); - return; - } - - // make the first five samples identical in both arrays - memcpy(pOutputArray, pInputArray, 13 * 4); - - // initialize values - int bm1 = 0; - int bm2 = 0; - int bm3 = 0; - int bm4 = 0; - int bm5 = 0; - int bm6 = 0; - int bm7 = 0; - int bm8 = 0; - int bm9 = 0; - int bm10 = 0; - int bm11 = 0; - int bm12 = 0; - int bm13 = 0; - - int m2 = 64; - - int m3 = 28; - int m4 = 16; - int OP0; - int OP1 = pOutputArray[12]; - int p4 = pInputArray[12]; - int p3 = (pInputArray[12] - pInputArray[11]) << 1; - int p2 = pInputArray[12] + ((pInputArray[10] - pInputArray[11]) << 3);// - pInputArray[3] + pInputArray[2]; - int bp1 = pOutputArray[12]; - int bp2 = pOutputArray[11]; - int bp3 = pOutputArray[10]; - int bp4 = pOutputArray[9]; - int bp5 = pOutputArray[8]; - int bp6 = pOutputArray[7]; - int bp7 = pOutputArray[6]; - int bp8 = pOutputArray[5]; - int bp9 = pOutputArray[4]; - int bp10 = pOutputArray[3]; - int bp11 = pOutputArray[2]; - int bp12 = pOutputArray[1]; - int bp13 = pOutputArray[0]; - - for (q = 13; q < NumberOfElements; q++) - { - pInputArray[q] = pInputArray[q] - 1; - OP0 = (pInputArray[q] - ((bp1 * bm1) >> 8) + ((bp2 * bm2) >> 8) - ((bp3 * bm3) >> 8) - ((bp4 * bm4) >> 8) - ((bp5 * bm5) >> 8) - ((bp6 * bm6) >> 8) - ((bp7 * bm7) >> 8) - ((bp8 * bm8) >> 8) - ((bp9 * bm9) >> 8) + ((bp10 * bm10) >> 8) + ((bp11 * bm11) >> 8) + ((bp12 * bm12) >> 8) + ((bp13 * bm13) >> 8)); - - if (pInputArray[q] > 0) - { - bm1 -= bp1 > 0 ? 1 : -1; - bm2 += bp2 >= 0 ? 1 : -1; - bm3 -= bp3 > 0 ? 1 : -1; - bm4 -= bp4 >= 0 ? 1 : -1; - bm5 -= bp5 > 0 ? 1 : -1; - bm6 -= bp6 >= 0 ? 1 : -1; - bm7 -= bp7 > 0 ? 1 : -1; - bm8 -= bp8 >= 0 ? 1 : -1; - bm9 -= bp9 > 0 ? 1 : -1; - bm10 += bp10 >= 0 ? 1 : -1; - bm11 += bp11 > 0 ? 1 : -1; - bm12 += bp12 >= 0 ? 1 : -1; - bm13 += bp13 > 0 ? 1 : -1; - } - else if (pInputArray[q] < 0) - { - bm1 -= bp1 <= 0 ? 1 : -1; - bm2 += bp2 < 0 ? 1 : -1; - bm3 -= bp3 <= 0 ? 1 : -1; - bm4 -= bp4 < 0 ? 1 : -1; - bm5 -= bp5 <= 0 ? 1 : -1; - bm6 -= bp6 < 0 ? 1 : -1; - bm7 -= bp7 <= 0 ? 1 : -1; - bm8 -= bp8 < 0 ? 1 : -1; - bm9 -= bp9 <= 0 ? 1 : -1; - bm10 += bp10 < 0 ? 1 : -1; - bm11 += bp11 <= 0 ? 1 : -1; - bm12 += bp12 < 0 ? 1 : -1; - bm13 += bp13 <= 0 ? 1 : -1; - } - - bp13 = bp12; - bp12 = bp11; - bp11 = bp10; - bp10 = bp9; - bp9 = bp8; - bp8 = bp7; - bp7 = bp6; - bp6 = bp5; - bp5 = bp4; - bp4 = bp3; - bp3 = bp2; - bp2 = bp1; - bp1 = OP0; - - pInputArray[q] = OP0 + ((p2 * m2) >> 11) + ((p3 * m3) >> 9) + ((p4 * m4) >> 9); - - if (OP0 > 0) - { - m2 -= p2 > 0 ? -1 : 1; - m3 -= p3 > 0 ? -1 : 1; - m4 -= p4 > 0 ? -1 : 1; - } - else if (OP0 < 0) - { - m2 -= p2 > 0 ? 1 : -1; - m3 -= p3 > 0 ? 1 : -1; - m4 -= p4 > 0 ? 1 : -1; - } - - p2 = pInputArray[q] + ((pInputArray[q - 2] - pInputArray[q - 1]) << 3); - p3 = (pInputArray[q] - pInputArray[q - 1]) << 1; - p4 = pInputArray[q]; - pOutputArray[q] = pInputArray[q];// + ((p3 * m3) >> 9); - } - - m4 = 370; - int m5 = 3900; - - pOutputArray[1] = pInputArray[1] + pOutputArray[0]; - pOutputArray[2] = pInputArray[2] + pOutputArray[1]; - pOutputArray[3] = pInputArray[3] + pOutputArray[2]; - pOutputArray[4] = pInputArray[4] + pOutputArray[3]; - pOutputArray[5] = pInputArray[5] + pOutputArray[4]; - pOutputArray[6] = pInputArray[6] + pOutputArray[5]; - pOutputArray[7] = pInputArray[7] + pOutputArray[6]; - pOutputArray[8] = pInputArray[8] + pOutputArray[7]; - pOutputArray[9] = pInputArray[9] + pOutputArray[8]; - pOutputArray[10] = pInputArray[10] + pOutputArray[9]; - pOutputArray[11] = pInputArray[11] + pOutputArray[10]; - pOutputArray[12] = pInputArray[12] + pOutputArray[11]; - - p4 = (2 * pInputArray[12]) - pInputArray[11]; - int p6 = 0; - int p5 = pOutputArray[12]; - int IP0, IP1; - int m6 = 0; - - IP1 = pInputArray[12]; - for (q = 13; q < NumberOfElements; q++) - { - IP0 = pOutputArray[q] + ((p4 * m4) >> 9) - ((p6 * m6) >> 10); - (pOutputArray[q] ^ p4) >= 0 ? m4++ : m4--; - (pOutputArray[q] ^ p6) >= 0 ? m6-- : m6++; - p4 = (2 * IP0) - IP1; - p6 = IP0; - - pOutputArray[q] = IP0 + ((p5 * 31) >> 5); - p5 = pOutputArray[q]; - - IP1 = IP0; - } -} - -void CAntiPredictorHigh3700To3800::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) -{ - // the frame to start prediction on - #define FIRST_ELEMENT 16 - - int x = 100; - int y = -25; - - // short frame handling - if (NumberOfElements < 20) - { - memcpy(pOutputArray, pInputArray, NumberOfElements * 4); - return; - } - - // make the first five samples identical in both arrays - memcpy(pOutputArray, pInputArray, FIRST_ELEMENT * 4); - - // variable declares and initializations - int bm[FIRST_ELEMENT]; memset(bm, 0, FIRST_ELEMENT * 4); - int m2 = 64, m3 = 115, m4 = 64, m5 = 740, m6 = 0; - int p4 = pInputArray[FIRST_ELEMENT - 1]; - int p3 = (pInputArray[FIRST_ELEMENT - 1] - pInputArray[FIRST_ELEMENT - 2]) << 1; - int p2 = pInputArray[FIRST_ELEMENT - 1] + ((pInputArray[FIRST_ELEMENT - 3] - pInputArray[FIRST_ELEMENT - 2]) << 3);// - pInputArray[3] + pInputArray[2]; - int *op = &pOutputArray[FIRST_ELEMENT]; - int *ip = &pInputArray[FIRST_ELEMENT]; - int IPP2 = ip[-2]; - int IPP1 = ip[-1]; - int p7 = 2 * ip[-1] - ip[-2]; - int opp = op[-1]; - int Original; - - // undo the initial prediction stuff - for (int q = 1; q < FIRST_ELEMENT; q++) { - pOutputArray[q] += pOutputArray[q - 1]; - } - - // pump the primary loop - for (;op < &pOutputArray[NumberOfElements]; op++, ip++) { - - Original = *ip - 1; - *ip = Original - (((ip[-1] * bm[0]) + (ip[-2] * bm[1]) + (ip[-3] * bm[2]) + (ip[-4] * bm[3]) + (ip[-5] * bm[4]) + (ip[-6] * bm[5]) + (ip[-7] * bm[6]) + (ip[-8] * bm[7]) + (ip[-9] * bm[8]) + (ip[-10] * bm[9]) + (ip[-11] * bm[10]) + (ip[-12] * bm[11]) + (ip[-13] * bm[12]) + (ip[-14] * bm[13]) + (ip[-15] * bm[14]) + (ip[-16] * bm[15])) >> 8); - - if (Original > 0) - { - bm[0] -= ip[-1] > 0 ? 1 : -1; - bm[1] += ((unsigned int(ip[-2]) >> 30) & 2) - 1; - bm[2] -= ip[-3] > 0 ? 1 : -1; - bm[3] += ((unsigned int(ip[-4]) >> 30) & 2) - 1; - bm[4] -= ip[-5] > 0 ? 1 : -1; - bm[5] += ((unsigned int(ip[-6]) >> 30) & 2) - 1; - bm[6] -= ip[-7] > 0 ? 1 : -1; - bm[7] += ((unsigned int(ip[-8]) >> 30) & 2) - 1; - bm[8] -= ip[-9] > 0 ? 1 : -1; - bm[9] += ((unsigned int(ip[-10]) >> 30) & 2) - 1; - bm[10] -= ip[-11] > 0 ? 1 : -1; - bm[11] += ((unsigned int(ip[-12]) >> 30) & 2) - 1; - bm[12] -= ip[-13] > 0 ? 1 : -1; - bm[13] += ((unsigned int(ip[-14]) >> 30) & 2) - 1; - bm[14] -= ip[-15] > 0 ? 1 : -1; - bm[15] += ((unsigned int(ip[-16]) >> 30) & 2) - 1; - } - else if (Original < 0) - { - bm[0] -= ip[-1] <= 0 ? 1 : -1; - bm[1] -= ((unsigned int(ip[-2]) >> 30) & 2) - 1; - bm[2] -= ip[-3] <= 0 ? 1 : -1; - bm[3] -= ((unsigned int(ip[-4]) >> 30) & 2) - 1; - bm[4] -= ip[-5] <= 0 ? 1 : -1; - bm[5] -= ((unsigned int(ip[-6]) >> 30) & 2) - 1; - bm[6] -= ip[-7] <= 0 ? 1 : -1; - bm[7] -= ((unsigned int(ip[-8]) >> 30) & 2) - 1; - bm[8] -= ip[-9] <= 0 ? 1 : -1; - bm[9] -= ((unsigned int(ip[-10]) >> 30) & 2) - 1; - bm[10] -= ip[-11] <= 0 ? 1 : -1; - bm[11] -= ((unsigned int(ip[-12]) >> 30) & 2) - 1; - bm[12] -= ip[-13] <= 0 ? 1 : -1; - bm[13] -= ((unsigned int(ip[-14]) >> 30) & 2) - 1; - bm[14] -= ip[-15] <= 0 ? 1 : -1; - bm[15] -= ((unsigned int(ip[-16]) >> 30) & 2) - 1; - } - - ///////////////////////////////////////////// - *op = *ip + (((p2 * m2) + (p3 * m3) + (p4 * m4)) >> 11); - - if (*ip > 0) - { - m2 -= p2 > 0 ? -1 : 1; - m3 -= p3 > 0 ? -4 : 4; - m4 -= p4 > 0 ? -4 : 4; - } - else if (*ip < 0) - { - m2 -= p2 > 0 ? 1 : -1; - m3 -= p3 > 0 ? 4 : -4; - m4 -= p4 > 0 ? 4 : -4; - } - - p4 = *op; - p2 = p4 + ((IPP2 - IPP1) << 3); - p3 = (p4 - IPP1) << 1; - - IPP2 = IPP1; - IPP1 = p4; - - ///////////////////////////////////////////// - *op += (((p7 * m5) - (opp * m6)) >> 10); - - (IPP1 ^ p7) >= 0 ? m5+=2 : m5-=2; - (IPP1 ^ opp) >= 0 ? m6-- : m6++; - - p7 = 2 * *op - opp; - opp = *op; - - ///////////////////////////////////////////// - *op += ((op[-1] * 31) >> 5); - } -} - -void CAntiPredictorHigh3800ToCurrent::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) -{ - // the frame to start prediction on - #define FIRST_ELEMENT 16 - - // short frame handling - if (NumberOfElements < 20) - { - memcpy(pOutputArray, pInputArray, NumberOfElements * 4); - return; - } - - // make the first five samples identical in both arrays - memcpy(pOutputArray, pInputArray, FIRST_ELEMENT * 4); - - // variable declares and initializations - int bm[FIRST_ELEMENT]; memset(bm, 0, FIRST_ELEMENT * 4); - int m2 = 64, m3 = 115, m4 = 64, m5 = 740, m6 = 0; - int p4 = pInputArray[FIRST_ELEMENT - 1]; - int p3 = (pInputArray[FIRST_ELEMENT - 1] - pInputArray[FIRST_ELEMENT - 2]) << 1; - int p2 = pInputArray[FIRST_ELEMENT - 1] + ((pInputArray[FIRST_ELEMENT - 3] - pInputArray[FIRST_ELEMENT - 2]) << 3);// - pInputArray[3] + pInputArray[2]; - int *op = &pOutputArray[FIRST_ELEMENT]; - int *ip = &pInputArray[FIRST_ELEMENT]; - int IPP2 = ip[-2]; - int IPP1 = ip[-1]; - int p7 = 2 * ip[-1] - ip[-2]; - int opp = op[-1]; - - // undo the initial prediction stuff - for (int q = 1; q < FIRST_ELEMENT; q++) - { - pOutputArray[q] += pOutputArray[q - 1]; - } - - // pump the primary loop - for (;op < &pOutputArray[NumberOfElements]; op++, ip++) - { - - unsigned int *pip = (unsigned int *) &ip[-FIRST_ELEMENT]; - int *pbm = &bm[0]; - int nDotProduct = 0; - - if (*ip > 0) - { - EXPAND_16_TIMES(nDotProduct += *pip * *pbm; *pbm++ += ((*pip++ >> 30) & 2) - 1;) - } - else if (*ip < 0) - { - EXPAND_16_TIMES(nDotProduct += *pip * *pbm; *pbm++ -= ((*pip++ >> 30) & 2) - 1;) - } - else - { - EXPAND_16_TIMES(nDotProduct += *pip++ * *pbm++;) - } - - *ip -= (nDotProduct >> 9); - - ///////////////////////////////////////////// - *op = *ip + (((p2 * m2) + (p3 * m3) + (p4 * m4)) >> 11); - - if (*ip > 0) - { - m2 -= ((p2 >> 30) & 2) - 1; - m3 -= ((p3 >> 28) & 8) - 4; - m4 -= ((p4 >> 28) & 8) - 4; - - } - else if (*ip < 0) - { - m2 += ((p2 >> 30) & 2) - 1; - m3 += ((p3 >> 28) & 8) - 4; - m4 += ((p4 >> 28) & 8) - 4; - } - - - p2 = *op + ((IPP2 - p4) << 3); - p3 = (*op - p4) << 1; - IPP2 = p4; - p4 = *op; - - ///////////////////////////////////////////// - *op += (((p7 * m5) - (opp * m6)) >> 10); - - if (p4 > 0) - { - m5 -= ((p7 >> 29) & 4) - 2; - m6 += ((opp >> 30) & 2) - 1; - } - else if (p4 < 0) - { - m5 += ((p7 >> 29) & 4) - 2; - m6 -= ((opp >> 30) & 2) - 1; - } - - p7 = 2 * *op - opp; - opp = *op; - - ///////////////////////////////////////////// - *op += ((op[-1] * 31) >> 5); - } - - #undef FIRST_ELEMENT -} - -#endif // #ifdef ENABLE_COMPRESSION_MODE_HIGH - -#endif // #ifdef BACKWARDS_COMPATIBILITY diff --git a/MAC_SDK/Source/MACLib/Old/AntiPredictorNormal.cpp b/MAC_SDK/Source/MACLib/Old/AntiPredictorNormal.cpp deleted file mode 100644 index 9a8daea..0000000 --- a/MAC_SDK/Source/MACLib/Old/AntiPredictorNormal.cpp +++ /dev/null @@ -1,262 +0,0 @@ -#include "All.h" -#ifdef BACKWARDS_COMPATIBILITY - -#include "Anti-Predictor.h" -#ifdef ENABLE_COMPRESSION_MODE_NORMAL - -void CAntiPredictorNormal0000To3320::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) -{ - // variable declares - int *ip, *op, *op1, *op2; - int p, pw; - int m; - - // short frame handling - if (NumberOfElements < 32) - { - memcpy(pOutputArray, pInputArray, NumberOfElements * 4); - return; - } - - //////////////////////////////////////// - // order 3 - //////////////////////////////////////// - memcpy(pOutputArray, pInputArray, 32); - - // initialize values - m = 300; - op = &pOutputArray[8]; - op1 = &pOutputArray[7]; - op2 = &pOutputArray[6]; - - // make the first prediction - p = (pOutputArray[7] * 3) - (pOutputArray[6] * 3) + pOutputArray[5]; - pw = (p * m) >> 12; - - // loop through the array - for (ip = &pInputArray[8]; ip < &pInputArray[NumberOfElements]; ip++, op++, op1++, op2++) { - - // figure the output value - *op = *ip + pw; - - // adjust m - if (*ip > 0) - m += (p > 0) ? 4 : -4; - else if (*ip < 0) - m += (p > 0) ? -4 : 4; - - // make the next prediction - p = (*op * 3) - (*op1 * 3) + *op2; - pw = (p * m) >> 12; - } - - - /////////////////////////////////////// - // order 2 - /////////////////////////////////////// - memcpy(pInputArray, pOutputArray, 32); - m = 3000; - - op1 = &pInputArray[7]; - p = (*op1 * 2) - pInputArray[6]; - pw = (p * m) >> 12; - - for (op = &pInputArray[8], ip = &pOutputArray[8]; ip < &pOutputArray[NumberOfElements]; ip++, op++, op1++) - { - *op = *ip + pw; - - // adjust m - if (*ip > 0) - m += (p > 0) ? 12 : -12; - else if (*ip < 0) - m += (p > 0) ? -12 : 12; - - p = (*op * 2) - *op1; - pw = (p * m) >> 12; - - } - - /////////////////////////////////////// - // order 1 - /////////////////////////////////////// - pOutputArray[0] = pInputArray[0]; - pOutputArray[1] = pInputArray[1] + pOutputArray[0]; - pOutputArray[2] = pInputArray[2] + pOutputArray[1]; - pOutputArray[3] = pInputArray[3] + pOutputArray[2]; - pOutputArray[4] = pInputArray[4] + pOutputArray[3]; - pOutputArray[5] = pInputArray[5] + pOutputArray[4]; - pOutputArray[6] = pInputArray[6] + pOutputArray[5]; - pOutputArray[7] = pInputArray[7] + pOutputArray[6]; - - m = 3900; - - p = pOutputArray[7]; - pw = (p * m) >> 12; - - for (op = &pOutputArray[8], ip = &pInputArray[8]; ip < &pInputArray[NumberOfElements]; ip++, op++) { - *op = *ip + pw; - - // adjust m - if (*ip > 0) - m += (p > 0) ? 1 : -1; - else if (*ip < 0) - m += (p > 0) ? -1 : 1; - - p = *op; - pw = (p * m) >> 12; - } - -} - -void CAntiPredictorNormal3320To3800::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) -{ - // variable declares - int q; - - // short frame handling - if (NumberOfElements < 8) - { - memcpy(pOutputArray, pInputArray, NumberOfElements * 4); - return; - } - - // make the first five samples identical in both arrays - memcpy(pOutputArray, pInputArray, 20); - - // initialize values - int m1 = 0; - int m2 = 64; - int m3 = 28; - int OP0; - int OP1 = pOutputArray[4]; - - int p3 = (3 * (pOutputArray[4] - pOutputArray[3])) + pOutputArray[2]; - int p2 = pInputArray[4] + ((pInputArray[2] - pInputArray[3]) << 3) - pInputArray[1] + pInputArray[0]; - int p1 = pOutputArray[4]; - - for (q = 5; q < NumberOfElements; q++) - { - OP0 = pInputArray[q] + ((p1 * m1) >> 8); - (pInputArray[q] ^ p1) > 0 ? m1++ : m1--; - p1 = OP0; - - pInputArray[q] = OP0 + ((p2 * m2) >> 11); - (OP0 ^ p2) > 0 ? m2++ : m2--; - p2 = pInputArray[q] + ((pInputArray[q - 2] - pInputArray[q - 1]) << 3) - pInputArray[q - 3] + pInputArray[q - 4]; - - pOutputArray[q] = pInputArray[q] + ((p3 * m3) >> 9); - (pInputArray[q] ^ p3) > 0 ? m3++ : m3--; - p3 = (3 * (pOutputArray[q] - pOutputArray[q - 1])) + pOutputArray[q - 2]; - } - - int m4 = 370; - int m5 = 3900; - - pOutputArray[1] = pInputArray[1] + pOutputArray[0]; - pOutputArray[2] = pInputArray[2] + pOutputArray[1]; - pOutputArray[3] = pInputArray[3] + pOutputArray[2]; - pOutputArray[4] = pInputArray[4] + pOutputArray[3]; - - int p4 = (2 * pInputArray[4]) - pInputArray[3]; - int p5 = pOutputArray[4]; - int IP0, IP1; - - IP1 = pInputArray[4]; - for (q = 5; q < NumberOfElements; q++) - { - IP0 = pOutputArray[q] + ((p4 * m4) >> 9); - (pOutputArray[q] ^ p4) > 0 ? m4++ : m4--; - p4 = (2 * IP0) - IP1; - - pOutputArray[q] = IP0 + ((p5 * m5) >> 12); - (IP0 ^ p5) > 0 ? m5++ : m5--; - p5 = pOutputArray[q]; - - IP1 = IP0; - } -} - -void CAntiPredictorNormal3800ToCurrent::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements) -{ - // the frame to start prediction on - #define FIRST_ELEMENT 4 - - // short frame handling - if (NumberOfElements < 8) - { - memcpy(pOutputArray, pInputArray, NumberOfElements * 4); - return; - } - - // make the first five samples identical in both arrays - memcpy(pOutputArray, pInputArray, FIRST_ELEMENT * 4); - - // variable declares and initializations - int m2 = 64, m3 = 115, m4 = 64, m5 = 740, m6 = 0; - int p4 = pInputArray[FIRST_ELEMENT - 1]; - int p3 = (pInputArray[FIRST_ELEMENT - 1] - pInputArray[FIRST_ELEMENT - 2]) << 1; - int p2 = pInputArray[FIRST_ELEMENT - 1] + ((pInputArray[FIRST_ELEMENT - 3] - pInputArray[FIRST_ELEMENT - 2]) << 3);// - pInputArray[3] + pInputArray[2]; - int *op = &pOutputArray[FIRST_ELEMENT]; - int *ip = &pInputArray[FIRST_ELEMENT]; - int IPP2 = ip[-2]; - int p7 = 2 * ip[-1] - ip[-2]; - int opp = op[-1]; - - // undo the initial prediction stuff - for (int q = 1; q < FIRST_ELEMENT; q++) { - pOutputArray[q] += pOutputArray[q - 1]; - } - - // pump the primary loop - for (; op < &pOutputArray[NumberOfElements]; op++, ip++) { - - register int o = *op, i = *ip; - - ///////////////////////////////////////////// - o = i + (((p2 * m2) + (p3 * m3) + (p4 * m4)) >> 11); - - if (i > 0) - { - m2 -= ((p2 >> 30) & 2) - 1; - m3 -= ((p3 >> 28) & 8) - 4; - m4 -= ((p4 >> 28) & 8) - 4; - - } - else if (i < 0) - { - m2 += ((p2 >> 30) & 2) - 1; - m3 += ((p3 >> 28) & 8) - 4; - m4 += ((p4 >> 28) & 8) - 4; - } - - - p2 = o + ((IPP2 - p4) << 3); - p3 = (o - p4) << 1; - IPP2 = p4; - p4 = o; - - ///////////////////////////////////////////// - o += (((p7 * m5) - (opp * m6)) >> 10); - - if (p4 > 0) - { - m5 -= ((p7 >> 29) & 4) - 2; - m6 += ((opp >> 30) & 2) - 1; - } - else if (p4 < 0) - { - m5 += ((p7 >> 29) & 4) - 2; - m6 -= ((opp >> 30) & 2) - 1; - } - - p7 = 2 * o - opp; - opp = o; - - ///////////////////////////////////////////// - *op = o + ((op[-1] * 31) >> 5); - } -} - -#endif // #ifdef ENABLE_COMPRESSION_MODE_NORMAL - -#endif // #ifdef BACKWARDS_COMPATIBILITY diff --git a/MAC_SDK/Source/MACLib/Old/UnBitArrayOld.cpp b/MAC_SDK/Source/MACLib/Old/UnBitArrayOld.cpp deleted file mode 100644 index ce99936..0000000 --- a/MAC_SDK/Source/MACLib/Old/UnBitArrayOld.cpp +++ /dev/null @@ -1,353 +0,0 @@ -#include "All.h" -#ifdef BACKWARDS_COMPATIBILITY - -#include "../APEInfo.h" -#include "UnBitarrayOld.h" -#include "../BitArray.h" - -const uint32 K_SUM_MIN_BOUNDARY_OLD[32] = {0,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,0,0,0,0,0,0}; -const uint32 K_SUM_MAX_BOUNDARY_OLD[32] = {128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,0,0,0,0,0,0,0}; -const uint32 Powers_of_Two[32] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648}; -const uint32 Powers_of_Two_Reversed[32] = {2147483648,1073741824,536870912,268435456,134217728,67108864,33554432,16777216,8388608,4194304,2097152,1048576,524288,262144,131072,65536,32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1}; -const uint32 Powers_of_Two_Minus_One[33] = {0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535,131071,262143,524287,1048575,2097151,4194303,8388607,16777215,33554431,67108863,134217727,268435455,536870911,1073741823,2147483647,4294967295}; -const uint32 Powers_of_Two_Minus_One_Reversed[33] = {4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,8388607,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0}; - -const uint32 K_SUM_MIN_BOUNDARY[32] = {0,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,0,0,0,0}; -const uint32 K_SUM_MAX_BOUNDARY[32] = {32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,0,0,0,0,0}; - -/*********************************************************************************** -Construction -***********************************************************************************/ -CUnBitArrayOld::CUnBitArrayOld(IAPEDecompress * pAPEDecompress, int nVersion) -{ - int nBitArrayBytes = 262144; - - // calculate the bytes - if (nVersion <= 3880) - { - int nMaxFrameBytes = (pAPEDecompress->GetInfo(APE_INFO_BLOCKS_PER_FRAME) * 50) / 8; - nBitArrayBytes = 65536; - while (nBitArrayBytes < nMaxFrameBytes) - { - nBitArrayBytes <<= 1; - } - - nBitArrayBytes = max(nBitArrayBytes, 262144); - } - else if (nVersion <= 3890) - { - nBitArrayBytes = 65536; - } - else - { - // error - } - - CreateHelper(GET_IO(pAPEDecompress), nBitArrayBytes, nVersion); - - // set the refill threshold - if (m_nVersion <= 3880) - m_nRefillBitThreshold = (m_nBits - (16384 * 8)); - else - m_nRefillBitThreshold = (m_nBits - 512); -} - -CUnBitArrayOld::~CUnBitArrayOld() -{ - SAFE_ARRAY_DELETE(m_pBitArray) -} - -//////////////////////////////////////////////////////////////////////////////////// -// Gets the number of m_nBits of data left in the m_nCurrentBitIndex array -//////////////////////////////////////////////////////////////////////////////////// -uint32 CUnBitArrayOld::GetBitsRemaining() -{ - return (m_nElements * 32 - m_nCurrentBitIndex); -} - -//////////////////////////////////////////////////////////////////////////////////// -// Gets a rice value from the array -//////////////////////////////////////////////////////////////////////////////////// -uint32 CUnBitArrayOld::DecodeValueRiceUnsigned(uint32 k) -{ - // variable declares - uint32 v; - - // plug through the string of 0's (the overflow) - uint32 BitInitial = m_nCurrentBitIndex; - while (!(m_pBitArray[m_nCurrentBitIndex >> 5] & Powers_of_Two_Reversed[m_nCurrentBitIndex++ & 31])) {} - - // if k = 0, your done - if (k == 0) - return (m_nCurrentBitIndex - BitInitial - 1); - - // put the overflow value into v - v = (m_nCurrentBitIndex - BitInitial - 1) << k; - - return v | DecodeValueXBits(k); -} - -//////////////////////////////////////////////////////////////////////////////////// -// Get the optimal k for a given value -//////////////////////////////////////////////////////////////////////////////////// -__inline uint32 CUnBitArrayOld::Get_K(uint32 x) -{ - if (x == 0) return 0; - - uint32 k = 0; - while (x >= Powers_of_Two[++k]) {} - return k; -} - -unsigned int CUnBitArrayOld::DecodeValue(DECODE_VALUE_METHOD DecodeMethod, int nParam1, int nParam2) -{ - switch (DecodeMethod) - { - case DECODE_VALUE_METHOD_UNSIGNED_INT: - return DecodeValueXBits(32); - case DECODE_VALUE_METHOD_UNSIGNED_RICE: - return DecodeValueRiceUnsigned(nParam1); - case DECODE_VALUE_METHOD_X_BITS: - return DecodeValueXBits(nParam1); - } - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////////// -// Generates an array from the m_nCurrentBitIndexarray -//////////////////////////////////////////////////////////////////////////////////// -void CUnBitArrayOld::GenerateArrayOld(int* Output_Array, uint32 Number_of_Elements, int Minimum_nCurrentBitIndex_Array_Bytes) { - - //variable declarations - uint32 K_Sum; - uint32 q; - uint32 kmin, kmax; - uint32 k; - uint32 Max; - int *p1, *p2; - - // fill bit array if necessary - // could use seek information to determine what the max was... - uint32 Max_Bits_Needed = Number_of_Elements * 50; - - if (Minimum_nCurrentBitIndex_Array_Bytes > 0) - { - // this is actually probably double what is really needed - // we can only calculate the space needed for both arrays in multichannel - Max_Bits_Needed = ((Minimum_nCurrentBitIndex_Array_Bytes + 4) * 8); - } - - if (Max_Bits_Needed > GetBitsRemaining()) - FillBitArray(); - - // decode the first 5 elements (all k = 10) - Max = (Number_of_Elements < 5) ? Number_of_Elements : 5; - for (q = 0; q < Max; q++) - { - Output_Array[q] = DecodeValueRiceUnsigned(10); - } - - // quit if that was all - if (Number_of_Elements <= 5) - { - for (p2 = &Output_Array[0]; p2 < &Output_Array[Number_of_Elements]; p2++) - *p2 = (*p2 & 1) ? (*p2 >> 1) + 1 : -(*p2 >> 1); - return; - } - - // update k and K_Sum - K_Sum = Output_Array[0] + Output_Array[1] + Output_Array[2] + Output_Array[3] + Output_Array[4]; - k = Get_K(K_Sum / 10); - - // work through the rest of the elements before the primary loop - Max = (Number_of_Elements < 64) ? Number_of_Elements : 64; - for (q = 5; q < Max; q++) - { - Output_Array[q] = DecodeValueRiceUnsigned(k); - K_Sum += Output_Array[q]; - k = Get_K(K_Sum / (q + 1) / 2); - } - - // quit if that was all - if (Number_of_Elements <= 64) - { - for (p2 = &Output_Array[0]; p2 < &Output_Array[Number_of_Elements]; p2++) - *p2 = (*p2 & 1) ? (*p2 >> 1) + 1 : -(*p2 >> 1); - return; - } - - // set all of the variables up for the primary loop - uint32 v, Bit_Array_Index; - k = Get_K(K_Sum >> 7); - kmin = K_SUM_MIN_BOUNDARY_OLD[k]; - kmax = K_SUM_MAX_BOUNDARY_OLD[k]; - p1 = &Output_Array[64]; p2 = &Output_Array[0]; - - // the primary loop - for (p1 = &Output_Array[64], p2 = &Output_Array[0]; p1 < &Output_Array[Number_of_Elements]; p1++, p2++) - { - // plug through the string of 0's (the overflow) - uint32 Bit_Initial = m_nCurrentBitIndex; - while (!(m_pBitArray[m_nCurrentBitIndex >> 5] & Powers_of_Two_Reversed[m_nCurrentBitIndex++ & 31])) {} - - // if k = 0, your done - if (k == 0) - { - v = (m_nCurrentBitIndex - Bit_Initial - 1); - } - else - { - // put the overflow value into v - v = (m_nCurrentBitIndex - Bit_Initial - 1) << k; - - // store the bit information and incement the bit pointer by 'k' - Bit_Array_Index = m_nCurrentBitIndex >> 5; - unsigned int Bit_Index = m_nCurrentBitIndex & 31; - m_nCurrentBitIndex += k; - - // figure the extra bits on the left and the left value - int Left_Extra_Bits = (32 - k) - Bit_Index; - unsigned int Left_Value = m_pBitArray[Bit_Array_Index] & Powers_of_Two_Minus_One_Reversed[Bit_Index]; - - if (Left_Extra_Bits >= 0) - v |= (Left_Value >> Left_Extra_Bits); - else - v |= (Left_Value << -Left_Extra_Bits) | (m_pBitArray[Bit_Array_Index + 1] >> (32 + Left_Extra_Bits)); - } - - *p1 = v; - K_Sum += *p1 - *p2; - - // convert *p2 to unsigned - *p2 = (*p2 % 2) ? (*p2 >> 1) + 1 : -(*p2 >> 1); - - // adjust k if necessary - if ((K_Sum < kmin) || (K_Sum >= kmax)) - { - if (K_Sum < kmin) - while (K_Sum < K_SUM_MIN_BOUNDARY_OLD[--k]) {} - else - while (K_Sum >= K_SUM_MAX_BOUNDARY_OLD[++k]) {} - - kmax = K_SUM_MAX_BOUNDARY_OLD[k]; - kmin = K_SUM_MIN_BOUNDARY_OLD[k]; - } - } - - for (; p2 < &Output_Array[Number_of_Elements]; p2++) - *p2 = (*p2 & 1) ? (*p2 >> 1) + 1 : -(*p2 >> 1); -} - -void CUnBitArrayOld::GenerateArray(int *pOutputArray, int nElements, int nBytesRequired) -{ - if (m_nVersion < 3860) - { - GenerateArrayOld(pOutputArray, nElements, nBytesRequired); - } - else if (m_nVersion <= 3890) - { - GenerateArrayRice(pOutputArray, nElements, nBytesRequired); - } - else - { - // error - } -} - -void CUnBitArrayOld::GenerateArrayRice(int* Output_Array, uint32 Number_of_Elements, int Minimum_nCurrentBitIndex_Array_Bytes) -{ - ///////////////////////////////////////////////////////////////////////////// - // decode the bit array - ///////////////////////////////////////////////////////////////////////////// - - k = 10; - K_Sum = 1024 * 16; - - if (m_nVersion <= 3880) - { - // the primary loop - for (int *p1 = &Output_Array[0]; p1 < &Output_Array[Number_of_Elements]; p1++) - { - *p1 = DecodeValueNew(FALSE); - } - } - else - { - // the primary loop - for (int *p1 = &Output_Array[0]; p1 < &Output_Array[Number_of_Elements]; p1++) - { - *p1 = DecodeValueNew(TRUE); - } - } -} - -__inline int CUnBitArrayOld::DecodeValueNew(BOOL bCapOverflow) -{ - // make sure there is room for the data - // this is a little slower than ensuring a huge block to start with, but it's safer - if (m_nCurrentBitIndex > m_nRefillBitThreshold) - { - FillBitArray(); - } - - unsigned int v; - - // plug through the string of 0's (the overflow) - uint32 Bit_Initial = m_nCurrentBitIndex; - while (!(m_pBitArray[m_nCurrentBitIndex >> 5] & Powers_of_Two_Reversed[m_nCurrentBitIndex++ & 31])) {} - - int nOverflow = (m_nCurrentBitIndex - Bit_Initial - 1); - - if (bCapOverflow) - { - while (nOverflow >= 16) - { - k += 4; - nOverflow -= 16; - } - } - - // if k = 0, your done - if (k != 0) - { - // put the overflow value into v - v = nOverflow << k; - - // store the bit information and incement the bit pointer by 'k' - unsigned int Bit_Array_Index = m_nCurrentBitIndex >> 5; - unsigned int Bit_Index = m_nCurrentBitIndex & 31; - m_nCurrentBitIndex += k; - - // figure the extra bits on the left and the left value - int Left_Extra_Bits = (32 - k) - Bit_Index; - unsigned int Left_Value = m_pBitArray[Bit_Array_Index] & Powers_of_Two_Minus_One_Reversed[Bit_Index]; - - if (Left_Extra_Bits >= 0) - { - v |= (Left_Value >> Left_Extra_Bits); - } - else - { - v |= (Left_Value << -Left_Extra_Bits) | (m_pBitArray[Bit_Array_Index + 1] >> (32 + Left_Extra_Bits)); - } - } - else - { - v = nOverflow; - } - - // update K_Sum - K_Sum += v - ((K_Sum + 8) >> 4); - - // update k - if (K_Sum < K_SUM_MIN_BOUNDARY[k]) - k--; - else if (K_Sum >= K_SUM_MAX_BOUNDARY[k]) - k++; - - // convert to unsigned and save - return (v & 1) ? (v >> 1) + 1 : -(int(v >> 1)); -} - -#endif // #ifdef BACKWARDS_COMPATIBILITY diff --git a/MAC_SDK/Source/MACLib/Old/UnBitArrayOld.h b/MAC_SDK/Source/MACLib/Old/UnBitArrayOld.h deleted file mode 100644 index 8a5beb5..0000000 --- a/MAC_SDK/Source/MACLib/Old/UnBitArrayOld.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef APE_UNBITARRAY_OLD_H -#define APE_UNBITARRAY_OLD_H - -#include "All.h" -#ifdef BACKWARDS_COMPATIBILITY - -#include "../UnBitArrayBase.h" - -class IAPEDecompress; - -// decodes 0000 up to and including 3890 -class CUnBitArrayOld : public CUnBitArrayBase -{ -public: - - // construction/destruction - CUnBitArrayOld(IAPEDecompress *pAPEDecompress, int nVersion); - ~CUnBitArrayOld(); - - // functions - void GenerateArray(int *pOutputArray, int nElements, int nBytesRequired = -1); - unsigned int DecodeValue(DECODE_VALUE_METHOD DecodeMethod, int nParam1 = 0, int nParam2 = 0); - -private: - - void GenerateArrayOld(int* pOutputArray, uint32 NumberOfElements, int MinimumBitArrayBytes); - void GenerateArrayRice(int* pOutputArray, uint32 NumberOfElements, int MinimumBitArrayBytes); - - uint32 DecodeValueRiceUnsigned(uint32 k); - - // data - uint32 k; - uint32 K_Sum; - uint32 m_nRefillBitThreshold; - - // functions - __inline int DecodeValueNew(BOOL bCapOverflow); - uint32 GetBitsRemaining(); - __inline uint32 Get_K(uint32 x); -}; - -#endif - -#endif // #ifndef APE_UNBITARRAY_OLD_H - - diff --git a/MAC_SDK/Source/MACLib/Old/UnMAC.cpp b/MAC_SDK/Source/MACLib/Old/UnMAC.cpp deleted file mode 100644 index 43d3732..0000000 --- a/MAC_SDK/Source/MACLib/Old/UnMAC.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/***************************************************************************************** -UnMAC.cpp -Copyright (C) 2000-2001 by Matthew T. Ashland All Rights Reserved. - -CUnMAC - the main hub for decompression (manages all of the other components) - -Notes: - -none -*****************************************************************************************/ - -/***************************************************************************************** -Includes -*****************************************************************************************/ -#include "All.h" -#ifdef BACKWARDS_COMPATIBILITY - -#include "../APEInfo.h" -#include "UnMAC.h" -#include "GlobalFunctions.h" -#include "../UnBitArrayBase.h" -#include "Anti-Predictor.h" -#include "../Prepare.h" -#include "../UnBitArray.h" -#include "../NewPredictor.h" -#include "APEDecompressCore.h" - -/***************************************************************************************** -CUnMAC class construction -*****************************************************************************************/ -CUnMAC::CUnMAC() -{ - // initialize member variables - m_bInitialized = FALSE; - m_LastDecodedFrameIndex = -1; - m_pAPEDecompress = NULL; - - m_pAPEDecompressCore = NULL; - m_pPrepare = NULL; - - m_nBlocksProcessed = 0; - m_nCRC = 0; - -} - -/***************************************************************************************** -CUnMAC class destruction -*****************************************************************************************/ -CUnMAC::~CUnMAC() -{ - // uninitialize the decoder in case it isn't already - Uninitialize(); -} - -/***************************************************************************************** -Initialize -*****************************************************************************************/ -int CUnMAC::Initialize(IAPEDecompress *pAPEDecompress) -{ - // uninitialize if it is currently initialized - if (m_bInitialized) - Uninitialize(); - - if (pAPEDecompress == NULL) - { - Uninitialize(); - return ERROR_INITIALIZING_UNMAC; - } - - // set the member pointer to the IAPEDecompress class - m_pAPEDecompress = pAPEDecompress; - - // set the last decode frame to -1 so it forces a seek on start - m_LastDecodedFrameIndex = -1; - - m_pAPEDecompressCore = new CAPEDecompressCore(GET_IO(pAPEDecompress), pAPEDecompress); - m_pPrepare = new CPrepare; - - // set the initialized flag to TRUE - m_bInitialized = TRUE; - - m_pAPEDecompress->GetInfo(APE_INFO_WAVEFORMATEX, (int) &m_wfeInput); - - // return a successful value - return ERROR_SUCCESS; -} - -/***************************************************************************************** -Uninitialize -*****************************************************************************************/ -int CUnMAC::Uninitialize() -{ - if (m_bInitialized) - { - SAFE_DELETE(m_pAPEDecompressCore) - SAFE_DELETE(m_pPrepare) - - // clear the APE info pointer - m_pAPEDecompress = NULL; - - // set the last decoded frame again - m_LastDecodedFrameIndex = -1; - - // set the initialized flag to FALSE - m_bInitialized = FALSE; - } - - return ERROR_SUCCESS; -} - -/***************************************************************************************** -Decompress frame -*****************************************************************************************/ -int CUnMAC::DecompressFrame(unsigned char *pOutputData, int32 FrameIndex, int CPULoadBalancingFactor) -{ - return DecompressFrameOld(pOutputData, FrameIndex, CPULoadBalancingFactor); -} - -/***************************************************************************************** -Seek to the proper frame (if necessary) and do any alignment of the bit array -*****************************************************************************************/ -int CUnMAC::SeekToFrame(int FrameIndex) -{ - if (GET_FRAMES_START_ON_BYTES_BOUNDARIES(m_pAPEDecompress)) - { - if ((m_LastDecodedFrameIndex == -1) || ((FrameIndex - 1) != m_LastDecodedFrameIndex)) - { - int SeekRemainder = (m_pAPEDecompress->GetInfo(APE_INFO_SEEK_BYTE, FrameIndex) - m_pAPEDecompress->GetInfo(APE_INFO_SEEK_BYTE, 0)) % 4; - m_pAPEDecompressCore->GetUnBitArrray()->FillAndResetBitArray(m_pAPEDecompress->GetInfo(APE_INFO_SEEK_BYTE, FrameIndex) - SeekRemainder, SeekRemainder * 8); - } - else - { - m_pAPEDecompressCore->GetUnBitArrray()->AdvanceToByteBoundary(); - } - } - else - { - if ((m_LastDecodedFrameIndex == -1) || ((FrameIndex - 1) != m_LastDecodedFrameIndex)) - { - m_pAPEDecompressCore->GetUnBitArrray()->FillAndResetBitArray(m_pAPEDecompress->GetInfo(APE_INFO_SEEK_BYTE, FrameIndex), m_pAPEDecompress->GetInfo(APE_INFO_SEEK_BIT, FrameIndex)); - } - } - - return ERROR_SUCCESS; -} - -/***************************************************************************************** -Old code for frame decompression -*****************************************************************************************/ -int CUnMAC::DecompressFrameOld(unsigned char *pOutputData, int32 FrameIndex, int CPULoadBalancingFactor) -{ - // error check the parameters (too high of a frame index, etc.) - if (FrameIndex >= m_pAPEDecompress->GetInfo(APE_INFO_TOTAL_FRAMES)) { return ERROR_SUCCESS; } - - // get the number of samples in the frame - int nBlocks = 0; - nBlocks = ((FrameIndex + 1) >= m_pAPEDecompress->GetInfo(APE_INFO_TOTAL_FRAMES)) ? m_pAPEDecompress->GetInfo(APE_INFO_FINAL_FRAME_BLOCKS) : m_pAPEDecompress->GetInfo(APE_INFO_BLOCKS_PER_FRAME); - if (nBlocks == 0) - return -1; // nothing to do (file must be zero length) (have to return error) - - // take care of seeking and frame alignment - if (SeekToFrame(FrameIndex) != 0) { return -1; } - - // get the checksum - unsigned int nSpecialCodes = 0; - uint32 nStoredCRC = 0; - - if (GET_USES_CRC(m_pAPEDecompress) == FALSE) - { - nStoredCRC = m_pAPEDecompressCore->GetUnBitArrray()->DecodeValue(DECODE_VALUE_METHOD_UNSIGNED_RICE, 30); - if (nStoredCRC == 0) - { - nSpecialCodes = SPECIAL_FRAME_LEFT_SILENCE | SPECIAL_FRAME_RIGHT_SILENCE; - } - } - else - { - nStoredCRC = m_pAPEDecompressCore->GetUnBitArrray()->DecodeValue(DECODE_VALUE_METHOD_UNSIGNED_INT); - - // get any 'special' codes if the file uses them (for silence, FALSE stereo, etc.) - nSpecialCodes = 0; - if (GET_USES_SPECIAL_FRAMES(m_pAPEDecompress)) - { - if (nStoredCRC & 0x80000000) - { - nSpecialCodes = m_pAPEDecompressCore->GetUnBitArrray()->DecodeValue(DECODE_VALUE_METHOD_UNSIGNED_INT); - } - nStoredCRC &= 0x7FFFFFFF; - } - } - - // the CRC that will be figured during decompression - uint32 CRC = 0xFFFFFFFF; - - // decompress and convert from (x,y) -> (l,r) - // sort of int and ugly.... sorry - if (m_pAPEDecompress->GetInfo(APE_INFO_CHANNELS) == 2) - { - m_pAPEDecompressCore->GenerateDecodedArrays(nBlocks, nSpecialCodes, FrameIndex, CPULoadBalancingFactor); - - WAVEFORMATEX WaveFormatEx; m_pAPEDecompress->GetInfo(APE_INFO_WAVEFORMATEX, (int) &WaveFormatEx); - m_pPrepare->UnprepareOld(m_pAPEDecompressCore->GetDataX(), m_pAPEDecompressCore->GetDataY(), nBlocks, &WaveFormatEx, - pOutputData, (unsigned int *) &CRC, (int *) &nSpecialCodes, m_pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION)); - } - else if (m_pAPEDecompress->GetInfo(APE_INFO_CHANNELS) == 1) - { - m_pAPEDecompressCore->GenerateDecodedArrays(nBlocks, nSpecialCodes, FrameIndex, CPULoadBalancingFactor); - - WAVEFORMATEX WaveFormatEx; m_pAPEDecompress->GetInfo(APE_INFO_WAVEFORMATEX, (int) &WaveFormatEx); - m_pPrepare->UnprepareOld(m_pAPEDecompressCore->GetDataX(), NULL, nBlocks, &WaveFormatEx, - pOutputData, (unsigned int *) &CRC, (int *) &nSpecialCodes, m_pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION)); - } - - if (GET_USES_SPECIAL_FRAMES(m_pAPEDecompress)) - { - CRC >>= 1; - } - - // check the CRC - if (GET_USES_CRC(m_pAPEDecompress) == FALSE) - { - uint32 nChecksum = CalculateOldChecksum(m_pAPEDecompressCore->GetDataX(), m_pAPEDecompressCore->GetDataY(), m_pAPEDecompress->GetInfo(APE_INFO_CHANNELS), nBlocks); - if (nChecksum != nStoredCRC) - return -1; - } - else - { - if (CRC != nStoredCRC) - return -1; - } - - m_LastDecodedFrameIndex = FrameIndex; - return nBlocks; -} - - -/***************************************************************************************** -Figures the old checksum using the X,Y data -*****************************************************************************************/ -uint32 CUnMAC::CalculateOldChecksum(int *pDataX, int *pDataY, int nChannels, int nBlocks) -{ - uint32 nChecksum = 0; - - if (nChannels == 2) - { - for (int z = 0; z < nBlocks; z++) - { - int R = pDataX[z] - (pDataY[z] / 2); - int L = R + pDataY[z]; - nChecksum += (labs(R) + labs(L)); - } - } - else if (nChannels == 1) - { - for (int z = 0; z < nBlocks; z++) - nChecksum += labs(pDataX[z]); - } - - return nChecksum; -} - -#endif // #ifdef BACKWARDS_COMPATIBILITY diff --git a/MAC_SDK/Source/MACLib/Old/UnMAC.h b/MAC_SDK/Source/MACLib/Old/UnMAC.h deleted file mode 100644 index 20263eb..0000000 --- a/MAC_SDK/Source/MACLib/Old/UnMAC.h +++ /dev/null @@ -1,69 +0,0 @@ -/***************************************************************************************** -UnMAC.h -Copyright (C) 2000-2001 by Matthew T. Ashland All Rights Reserved. - -Methods for decompressing or verifying APE files - -Notes: - -none -*****************************************************************************************/ - -#ifndef APE_UNMAC_H -#define APE_UNMAC_H - -#include "../BitArray.h" -#include "../UnBitArrayBase.h" - -class CAntiPredictor; -class CPrepare; -class CAPEDecompressCore; -class CPredictorBase; -class IPredictorDecompress; -class IAPEDecompress; - -/***************************************************************************************** -CUnMAC class... a class that allows decoding on a frame-by-frame basis -*****************************************************************************************/ -class CUnMAC -{ -public: - - // construction/destruction - CUnMAC(); - ~CUnMAC(); - - // functions - int Initialize(IAPEDecompress *pAPEDecompress); - int Uninitialize(); - int DecompressFrame(unsigned char *pOutputData, int32 FrameIndex, int CPULoadBalancingFactor = 0); - - int SeekToFrame(int FrameIndex); - -private: - - // data members - BOOL m_bInitialized; - int m_LastDecodedFrameIndex; - IAPEDecompress * m_pAPEDecompress; - CPrepare * m_pPrepare; - - CAPEDecompressCore * m_pAPEDecompressCore; - - // functions - void GenerateDecodedArrays(int nBlocks, int nSpecialCodes, int nFrameIndex, int nCPULoadBalancingFactor); - void GenerateDecodedArray(int *Input_Array, uint32 Number_of_Elements, int Frame_Index, CAntiPredictor *pAntiPredictor, int CPULoadBalancingFactor = 0); - - int CreateAntiPredictors(int nCompressionLevel, int nVersion); - - int DecompressFrameOld(unsigned char *pOutputData, int32 FrameIndex, int CPULoadBalancingFactor); - uint32 CalculateOldChecksum(int *pDataX, int *pDataY, int nChannels, int nBlocks); - -public: - - int m_nBlocksProcessed; - unsigned int m_nCRC; - unsigned int m_nStoredCRC; - WAVEFORMATEX m_wfeInput; -}; - -#endif // #ifndef APE_UNMAC_H diff --git a/MAC_SDK/Source/MACLib/Predictor.h b/MAC_SDK/Source/MACLib/Predictor.h deleted file mode 100644 index 9f6262e..0000000 --- a/MAC_SDK/Source/MACLib/Predictor.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef APE_PREDICTOR_H -#define APE_PREDICTOR_H - -/************************************************************************************************* -IPredictorCompress - the interface for compressing (predicting) data -*************************************************************************************************/ -class IPredictorCompress -{ -public: - IPredictorCompress(int nCompressionLevel) {} - virtual ~IPredictorCompress() {} - - virtual int CompressValue(int nA, int nB = 0) = 0; - virtual int Flush() = 0; -}; - -/************************************************************************************************* -IPredictorDecompress - the interface for decompressing (un-predicting) data -*************************************************************************************************/ -class IPredictorDecompress -{ -public: - IPredictorDecompress(int nCompressionLevel, int nVersion) {} - virtual ~IPredictorDecompress() {} - - virtual int DecompressValue(int nA, int nB = 0) = 0; - virtual int Flush() = 0; -}; - -#endif // #ifndef APE_PREDICTOR_H diff --git a/MAC_SDK/Source/MACLib/Prepare.cpp b/MAC_SDK/Source/MACLib/Prepare.cpp deleted file mode 100644 index 2e5a58c..0000000 --- a/MAC_SDK/Source/MACLib/Prepare.cpp +++ /dev/null @@ -1,510 +0,0 @@ -#include "All.h" -#include "Prepare.h" - -const uint32 CRC32_TABLE[256] = {0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368, - 4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850, - 2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918000,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117}; - -int CPrepare::Prepare(const unsigned char * pRawData, int nBytes, const WAVEFORMATEX * pWaveFormatEx, int * pOutputX, int *pOutputY, unsigned int *pCRC, int *pSpecialCodes, int *pPeakLevel) -{ - // error check the parameters - if (pRawData == NULL || pWaveFormatEx == NULL) - return ERROR_BAD_PARAMETER; - - // initialize the pointers that got passed in - *pCRC = 0xFFFFFFFF; - *pSpecialCodes = 0; - - // variables - uint32 CRC = 0xFFFFFFFF; - const int nTotalBlocks = nBytes / pWaveFormatEx->nBlockAlign; - int R,L; - - // the prepare code - - if (pWaveFormatEx->wBitsPerSample == 8) - { - if (pWaveFormatEx->nChannels == 2) - { - for (int nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++) - { - R = (int) (*((unsigned char *) pRawData) - 128); - L = (int) (*((unsigned char *) (pRawData + 1)) - 128); - - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - // check the peak - if (labs(L) > *pPeakLevel) - *pPeakLevel = labs(L); - if (labs(R) > *pPeakLevel) - *pPeakLevel = labs(R); - - // convert to x,y - pOutputY[nBlockIndex] = L - R; - pOutputX[nBlockIndex] = R + (pOutputY[nBlockIndex] / 2); - } - } - else if (pWaveFormatEx->nChannels == 1) - { - for (int nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++) - { - R = (int) (*((unsigned char *) pRawData) - 128); - - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - // check the peak - if (labs(R) > *pPeakLevel) - *pPeakLevel = labs(R); - - // convert to x,y - pOutputX[nBlockIndex] = R; - } - } - } - else if (pWaveFormatEx->wBitsPerSample == 24) - { - if (pWaveFormatEx->nChannels == 2) - { - for (int nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++) - { - uint32 nTemp = 0; - - nTemp |= (*pRawData << 0); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - nTemp |= (*pRawData << 8); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - nTemp |= (*pRawData << 16); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - if (nTemp & 0x800000) - R = (int) (nTemp & 0x7FFFFF) - 0x800000; - else - R = (int) (nTemp & 0x7FFFFF); - - nTemp = 0; - - nTemp |= (*pRawData << 0); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - nTemp |= (*pRawData << 8); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - nTemp |= (*pRawData << 16); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - if (nTemp & 0x800000) - L = (int) (nTemp & 0x7FFFFF) - 0x800000; - else - L = (int) (nTemp & 0x7FFFFF); - - // check the peak - if (labs(L) > *pPeakLevel) - *pPeakLevel = labs(L); - if (labs(R) > *pPeakLevel) - *pPeakLevel = labs(R); - - // convert to x,y - pOutputY[nBlockIndex] = L - R; - pOutputX[nBlockIndex] = R + (pOutputY[nBlockIndex] / 2); - - } - } - else if (pWaveFormatEx->nChannels == 1) - { - for (int nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++) - { - uint32 nTemp = 0; - - nTemp |= (*pRawData << 0); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - nTemp |= (*pRawData << 8); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - nTemp |= (*pRawData << 16); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - if (nTemp & 0x800000) - R = (int) (nTemp & 0x7FFFFF) - 0x800000; - else - R = (int) (nTemp & 0x7FFFFF); - - // check the peak - if (labs(R) > *pPeakLevel) - *pPeakLevel = labs(R); - - // convert to x,y - pOutputX[nBlockIndex] = R; - } - } - } - else - { - if (pWaveFormatEx->nChannels == 2) - { - int LPeak = 0; - int RPeak = 0; - int nBlockIndex = 0; - for (nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++) - { - - R = (int) *((int16 *) pRawData); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - L = (int) *((int16 *) pRawData); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - // check the peak - if (labs(L) > LPeak) - LPeak = labs(L); - if (labs(R) > RPeak) - RPeak = labs(R); - - // convert to x,y - pOutputY[nBlockIndex] = L - R; - pOutputX[nBlockIndex] = R + (pOutputY[nBlockIndex] / 2); - } - - if (LPeak == 0) { *pSpecialCodes |= SPECIAL_FRAME_LEFT_SILENCE; } - if (RPeak == 0) { *pSpecialCodes |= SPECIAL_FRAME_RIGHT_SILENCE; } - if (max(LPeak, RPeak) > *pPeakLevel) - { - *pPeakLevel = max(LPeak, RPeak); - } - - // check for pseudo-stereo files - nBlockIndex = 0; - while (pOutputY[nBlockIndex++] == 0) - { - if (nBlockIndex == (nBytes / 4)) - { - *pSpecialCodes |= SPECIAL_FRAME_PSEUDO_STEREO; - break; - } - } - - } - else if (pWaveFormatEx->nChannels == 1) - { - int nPeak = 0; - for (int nBlockIndex = 0; nBlockIndex < nTotalBlocks; nBlockIndex++) - { - R = (int) *((int16 *) pRawData); - - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *pRawData++]; - - // check the peak - if (labs(R) > nPeak) - nPeak = labs(R); - - //convert to x,y - pOutputX[nBlockIndex] = R; - } - - if (nPeak > *pPeakLevel) - *pPeakLevel = nPeak; - if (nPeak == 0) { *pSpecialCodes |= SPECIAL_FRAME_MONO_SILENCE; } - } - } - - CRC = CRC ^ 0xFFFFFFFF; - - // add the special code - CRC >>= 1; - - if (*pSpecialCodes != 0) - { - CRC |= (1 << 31); - } - - *pCRC = CRC; - - return ERROR_SUCCESS; -} - -void CPrepare::Unprepare(int X, int Y, const WAVEFORMATEX * pWaveFormatEx, unsigned char * pOutput, unsigned int * pCRC) -{ - #define CALCULATE_CRC_BYTE *pCRC = (*pCRC >> 8) ^ CRC32_TABLE[(*pCRC & 0xFF) ^ *pOutput++]; - // decompress and convert from (x,y) -> (l,r) - // sort of long and ugly.... sorry - - if (pWaveFormatEx->nChannels == 2) - { - if (pWaveFormatEx->wBitsPerSample == 16) - { - // get the right and left values - int nR = X - (Y / 2); - int nL = nR + Y; - - // error check (for overflows) - if ((nR < -32768) || (nR > 32767) || (nL < -32768) || (nL > 32767)) - { - throw(-1); - } - - *(int16 *) pOutput = (int16) nR; - CALCULATE_CRC_BYTE - CALCULATE_CRC_BYTE - - *(int16 *) pOutput = (int16) nL; - CALCULATE_CRC_BYTE - CALCULATE_CRC_BYTE - } - else if (pWaveFormatEx->wBitsPerSample == 8) - { - unsigned char R = (X - (Y / 2) + 128); - *pOutput = R; - CALCULATE_CRC_BYTE - *pOutput = (unsigned char) (R + Y); - CALCULATE_CRC_BYTE - } - else if (pWaveFormatEx->wBitsPerSample == 24) - { - int32 RV, LV; - - RV = X - (Y / 2); - LV = RV + Y; - - uint32 nTemp = 0; - if (RV < 0) - nTemp = ((uint32) (RV + 0x800000)) | 0x800000; - else - nTemp = (uint32) RV; - - *pOutput = (unsigned char) ((nTemp >> 0) & 0xFF); - CALCULATE_CRC_BYTE - *pOutput = (unsigned char) ((nTemp >> 8) & 0xFF); - CALCULATE_CRC_BYTE - *pOutput = (unsigned char) ((nTemp >> 16) & 0xFF); - CALCULATE_CRC_BYTE - - nTemp = 0; - if (LV < 0) - nTemp = ((uint32) (LV + 0x800000)) | 0x800000; - else - nTemp = (uint32) LV; - - *pOutput = (unsigned char) ((nTemp >> 0) & 0xFF); - CALCULATE_CRC_BYTE - - *pOutput = (unsigned char) ((nTemp >> 8) & 0xFF); - CALCULATE_CRC_BYTE - - *pOutput = (unsigned char) ((nTemp >> 16) & 0xFF); - CALCULATE_CRC_BYTE - } - } - else if (pWaveFormatEx->nChannels == 1) - { - if (pWaveFormatEx->wBitsPerSample == 16) - { - int16 R = X; - - *(int16 *) pOutput = (int16) R; - CALCULATE_CRC_BYTE - CALCULATE_CRC_BYTE - } - else if (pWaveFormatEx->wBitsPerSample == 8) - { - unsigned char R = X + 128; - *pOutput = R; - CALCULATE_CRC_BYTE - } - else if (pWaveFormatEx->wBitsPerSample == 24) - { - int32 RV = X; - - uint32 nTemp = 0; - if (RV < 0) - nTemp = ((uint32) (RV + 0x800000)) | 0x800000; - else - nTemp = (uint32) RV; - - *pOutput = (unsigned char) ((nTemp >> 0) & 0xFF); - CALCULATE_CRC_BYTE - *pOutput = (unsigned char) ((nTemp >> 8) & 0xFF); - CALCULATE_CRC_BYTE - *pOutput = (unsigned char) ((nTemp >> 16) & 0xFF); - CALCULATE_CRC_BYTE - } - } -} - -#ifdef BACKWARDS_COMPATIBILITY - -int CPrepare::UnprepareOld(int *pInputX, int *pInputY, int nBlocks, const WAVEFORMATEX *pWaveFormatEx, unsigned char *pRawData, unsigned int *pCRC, int *pSpecialCodes, int nFileVersion) -{ - // the CRC that will be figured during decompression - uint32 CRC = 0xFFFFFFFF; - - // decompress and convert from (x,y) -> (l,r) - // sort of int and ugly.... sorry - if (pWaveFormatEx->nChannels == 2) - { - // convert the x,y data to raw data - if (pWaveFormatEx->wBitsPerSample == 16) - { - int16 R; - unsigned char *Buffer = &pRawData[0]; - int *pX = pInputX; - int *pY = pInputY; - - for (; pX < &pInputX[nBlocks]; pX++, pY++) - { - R = *pX - (*pY / 2); - - *(int16 *) Buffer = (int16) R; - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - - *(int16 *) Buffer = (int16) R + *pY; - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - } - } - else if (pWaveFormatEx->wBitsPerSample == 8) - { - unsigned char *R = (unsigned char *) &pRawData[0]; - unsigned char *L = (unsigned char *) &pRawData[1]; - - if (nFileVersion > 3830) - { - for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++, L+=2, R+=2) - { - *R = (unsigned char) (pInputX[SampleIndex] - (pInputY[SampleIndex] / 2) + 128); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *R]; - *L = (unsigned char) (*R + pInputY[SampleIndex]); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *L]; - } - } - else - { - for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++, L+=2, R+=2) - { - *R = (unsigned char) (pInputX[SampleIndex] - (pInputY[SampleIndex] / 2)); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *R]; - *L = (unsigned char) (*R + pInputY[SampleIndex]); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *L]; - - } - } - } - else if (pWaveFormatEx->wBitsPerSample == 24) - { - unsigned char *Buffer = (unsigned char *) &pRawData[0]; - int32 RV, LV; - - for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++) - { - RV = pInputX[SampleIndex] - (pInputY[SampleIndex] / 2); - LV = RV + pInputY[SampleIndex]; - - uint32 nTemp = 0; - if (RV < 0) - nTemp = ((uint32) (RV + 0x800000)) | 0x800000; - else - nTemp = (uint32) RV; - - *Buffer = (unsigned char) ((nTemp >> 0) & 0xFF); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - - *Buffer = (unsigned char) ((nTemp >> 8) & 0xFF); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - - *Buffer = (unsigned char) ((nTemp >> 16) & 0xFF); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - - nTemp = 0; - if (LV < 0) - nTemp = ((uint32) (LV + 0x800000)) | 0x800000; - else - nTemp = (uint32) LV; - - *Buffer = (unsigned char) ((nTemp >> 0) & 0xFF); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - - *Buffer = (unsigned char) ((nTemp >> 8) & 0xFF); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - - *Buffer = (unsigned char) ((nTemp >> 16) & 0xFF); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - } - } - } - else if (pWaveFormatEx->nChannels == 1) - { - // convert to raw data - if (pWaveFormatEx->wBitsPerSample == 8) - { - unsigned char *R = (unsigned char *) &pRawData[0]; - - if (nFileVersion > 3830) - { - for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++, R++) - { - *R = pInputX[SampleIndex] + 128; - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *R]; - } - } - else - { - for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++, R++) - { - *R = (unsigned char) (pInputX[SampleIndex]); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *R]; - } - } - - } - else if (pWaveFormatEx->wBitsPerSample == 24) - { - - unsigned char *Buffer = (unsigned char *) &pRawData[0]; - int32 RV; - for (int SampleIndex = 0; SampleIndex> 0) & 0xFF); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - - *Buffer = (unsigned char) ((nTemp >> 8) & 0xFF); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - - *Buffer = (unsigned char) ((nTemp >> 16) & 0xFF); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - } - } - else - { - unsigned char *Buffer = &pRawData[0]; - - for (int SampleIndex = 0; SampleIndex < nBlocks; SampleIndex++) - { - *(int16 *) Buffer = (int16) (pInputX[SampleIndex]); - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - CRC = (CRC >> 8) ^ CRC32_TABLE[(CRC & 0xFF) ^ *Buffer++]; - } - } - } - - CRC = CRC ^ 0xFFFFFFFF; - - *pCRC = CRC; - - return 0; -} - -#endif // #ifdef BACKWARDS_COMPATIBILITY diff --git a/MAC_SDK/Source/MACLib/Prepare.h b/MAC_SDK/Source/MACLib/Prepare.h deleted file mode 100644 index eb5a844..0000000 --- a/MAC_SDK/Source/MACLib/Prepare.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef APE_PREPARE_H -#define APE_PREPARE_H - -#define SPECIAL_FRAME_MONO_SILENCE 1 -#define SPECIAL_FRAME_LEFT_SILENCE 1 -#define SPECIAL_FRAME_RIGHT_SILENCE 2 -#define SPECIAL_FRAME_PSEUDO_STEREO 4 - -/***************************************************************************** -Manage the preparation stage of compression and decompression - -Tasks: - -1) convert data to 32-bit -2) convert L,R to X,Y -3) calculate the CRC -4) do simple analysis -5) check for the peak value -*****************************************************************************/ - -class IPredictorDecompress; - -class CPrepare -{ -public: - - int Prepare(const unsigned char * pRawData, int nBytes, const WAVEFORMATEX * pWaveFormatEx, int * pOutputX, int * pOutputY, unsigned int * pCRC, int * pSpecialCodes, int * pPeakLevel); - void Unprepare(int X, int Y, const WAVEFORMATEX * pWaveFormatEx, unsigned char * pOutput, unsigned int * pCRC); - - -#ifdef BACKWARDS_COMPATIBILITY - int UnprepareOld(int * pInputX, int *pInputY, int nBlocks, const WAVEFORMATEX * pWaveFormatEx, unsigned char * pRawData, unsigned int * pCRC, int * pSpecialCodes, int nFileVersion); -#endif - -}; - - -#endif // #ifndef APE_PREPARE_H diff --git a/MAC_SDK/Source/MACLib/ScaledFirstOrderFilter.h b/MAC_SDK/Source/MACLib/ScaledFirstOrderFilter.h deleted file mode 100644 index f4222dd..0000000 --- a/MAC_SDK/Source/MACLib/ScaledFirstOrderFilter.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef APE_SCALEDFIRSTORDERFILTER_H -#define APE_SCALEDFIRSTORDERFILTER_H - -template class CScaledFirstOrderFilter -{ -public: - - __inline void Flush() - { - m_nLastValue = 0; - } - - __inline int Compress(const int nInput) - { - int nRetVal = nInput - ((m_nLastValue * MULTIPLY) >> SHIFT); - m_nLastValue = nInput; - return nRetVal; - } - - __inline int Decompress(const int nInput) - { - m_nLastValue = nInput + ((m_nLastValue * MULTIPLY) >> SHIFT); - return m_nLastValue; - } - -protected: - - int m_nLastValue; -}; - -#endif // #ifndef APE_SCALEDFIRSTORDERFILTER_H diff --git a/MAC_SDK/Source/MACLib/StartFilter.h b/MAC_SDK/Source/MACLib/StartFilter.h deleted file mode 100644 index 821c659..0000000 --- a/MAC_SDK/Source/MACLib/StartFilter.h +++ /dev/null @@ -1,178 +0,0 @@ -#ifndef APE_START_FILTER_H -#define APE_START_FILTER_H - -class CStartFilter -{ -public: - - CStartFilter() - { - - } - - ~CStartFilter() - { - - - } - - void Flush() - { - m_rbInputA.Flush(); - m_rbInputB.Flush(); - - memset(m_aryMA, 0, sizeof(m_aryMA)); - memset(m_aryMB, 0, sizeof(m_aryMB)); - - m_Stage1FilterA1.Flush(); - m_Stage1FilterA2.Flush(); - m_Stage1FilterA3.Flush(); - - m_Stage1FilterB1.Flush(); - m_Stage1FilterB2.Flush(); - m_Stage1FilterB3.Flush(); - } - - void Compress(int & nA, int & nB) - { -/* - nA = m_Stage1FilterA1.Compress(nA); - nA = m_Stage1FilterA2.Compress(nA); - nA = m_Stage1FilterA3.Compress(nA); - - nB = m_Stage1FilterB1.Compress(nB); - nB = m_Stage1FilterB2.Compress(nB); - nB = m_Stage1FilterB3.Compress(nB); - return; -//*/ - - nA = m_Stage1FilterA1.Compress(nA); - nA = m_Stage1FilterA2.Compress(nA); -// nA = m_Stage1FilterA3.Compress(nA); - - nB = m_Stage1FilterB1.Compress(nB); - nB = m_Stage1FilterB2.Compress(nB); - - //int nTemp = nA; nA = nB; nB = nTemp; -// nB = m_Stage1FilterB3.Compress(nB); - -// nA = nA - nB; -// nB = nB + (nA / 2); - - -// return; - - m_rbInputA[0] = nA; m_rbInputB[0] = nB; - - { - int nPrediction1 = m_rbInputA[-1]; - int nPrediction2 = m_rbInputA[-2]; - int nPrediction3 = m_rbInputA[-1] - m_rbInputA[-2]; - int nPrediction4 = m_rbInputB[-1]; - - int nTotalPrediction = (nPrediction1 * m_aryMA[0]) + (nPrediction2 * m_aryMA[1]) - + (nPrediction3 * m_aryMA[2]) + (nPrediction4 * m_aryMA[3]); - int nOutput = nA - (nTotalPrediction >> 13); - - if (nOutput > 0) - { - m_aryMA[0] -= 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0); - m_aryMA[1] -= (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0; - m_aryMA[2] -= (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0; - m_aryMA[3] -= 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0); - } - else if (nOutput < 0) - { - m_aryMA[0] += 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0); - m_aryMA[1] += (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0; - m_aryMA[2] += (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0; - m_aryMA[3] += 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0); - } - - nA = nOutput; - } - { - int nPrediction1 = m_rbInputB[-1]; - int nPrediction2 = m_rbInputB[-2]; - int nPrediction3 = 0;//m_rbInputB[-1] - m_rbInputB[-2]; - int nPrediction4 = m_rbInputA[0]; - - int nTotalPrediction = (nPrediction1 * m_aryMB[0]) + (nPrediction2 * m_aryMB[1]) - + (nPrediction3 * m_aryMB[2]) + (nPrediction4 * m_aryMB[3]); - int nOutput = nB - (nTotalPrediction >> 13); - - if (nOutput > 0) - { - m_aryMB[0] -= 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0); - m_aryMB[1] -= (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0; - m_aryMB[2] -= (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0; - m_aryMB[3] -= 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0); - } - else if (nOutput < 0) - { - m_aryMB[0] += 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0); - m_aryMB[1] += (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0; - m_aryMB[2] += (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0; - m_aryMB[3] += 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0); - } - - nB = nOutput; - } - - - m_rbInputA.IncrementSafe(); - m_rbInputB.IncrementSafe(); - - -/* -// nInput = m_Filter1.Compress(nInput); - - m_rbInput[0] = nInput; - - int nPrediction1 = m_rbInput[-1]; - int nPrediction2 = (2 * m_rbInput[-1]) - m_rbInput[-2]; - int nPrediction3 = m_rbInput[-1] - m_rbInput[-2]; - int nPrediction4 = m_nLastOutput; - - int nTotalPrediction = ((nPrediction1) * m_aryM[0]) + (nPrediction2 * m_aryM[1]) - + ((nPrediction3 >> 1) * m_aryM[2]) + (nPrediction4 * m_aryM[3]); - int nOutput = nInput - (nTotalPrediction >> 13); - - if (nOutput > 0) - { - m_aryM[0] -= (nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0; - m_aryM[1] -= (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0; - m_aryM[2] -= (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0; - m_aryM[3] -= (nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0; - } - else if (nOutput < 0) - { - m_aryM[0] += (nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0; - m_aryM[1] += (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0; - m_aryM[2] += (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0; - m_aryM[3] += (nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0; - } - - m_nLastOutput = nOutput; - m_rbInput.IncrementSafe(); - - return nOutput; - //*/ - } - -protected: - - CScaledFirstOrderFilter<31, 5> m_Stage1FilterA1; - CScaledFirstOrderFilter<24, 5> m_Stage1FilterA2; - CScaledFirstOrderFilter<7, 5> m_Stage1FilterA3; - - CScaledFirstOrderFilter<31, 5> m_Stage1FilterB1; - CScaledFirstOrderFilter<24, 5> m_Stage1FilterB2; - CScaledFirstOrderFilter<7, 5> m_Stage1FilterB3; - - CRollBufferFast m_rbInputA; - CRollBufferFast m_rbInputB; - int m_aryMA[8]; int m_aryMB[8]; -}; - -#endif // #ifndef APE_START_FILTER_H diff --git a/MAC_SDK/Source/MACLib/UnBitArray.cpp b/MAC_SDK/Source/MACLib/UnBitArray.cpp deleted file mode 100644 index 97417e7..0000000 --- a/MAC_SDK/Source/MACLib/UnBitArray.cpp +++ /dev/null @@ -1,302 +0,0 @@ -#include "All.h" -#include "APEInfo.h" -#include "UnBitArray.h" -#include "BitArray.h" - -const uint32 POWERS_OF_TWO_MINUS_ONE_REVERSED[33] = {4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,8388607,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0}; - -const uint32 K_SUM_MIN_BOUNDARY[32] = {0,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,0,0,0,0}; - -const uint32 RANGE_TOTAL_1[65] = {0,14824,28224,39348,47855,53994,58171,60926,62682,63786,64463,64878,65126,65276,65365,65419,65450,65469,65480,65487,65491,65493,65494,65495,65496,65497,65498,65499,65500,65501,65502,65503,65504,65505,65506,65507,65508,65509,65510,65511,65512,65513,65514,65515,65516,65517,65518,65519,65520,65521,65522,65523,65524,65525,65526,65527,65528,65529,65530,65531,65532,65533,65534,65535,65536}; -const uint32 RANGE_WIDTH_1[64] = {14824,13400,11124,8507,6139,4177,2755,1756,1104,677,415,248,150,89,54,31,19,11,7,4,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; - -const uint32 RANGE_TOTAL_2[65] = {0,19578,36160,48417,56323,60899,63265,64435,64971,65232,65351,65416,65447,65466,65476,65482,65485,65488,65490,65491,65492,65493,65494,65495,65496,65497,65498,65499,65500,65501,65502,65503,65504,65505,65506,65507,65508,65509,65510,65511,65512,65513,65514,65515,65516,65517,65518,65519,65520,65521,65522,65523,65524,65525,65526,65527,65528,65529,65530,65531,65532,65533,65534,65535,65536}; -const uint32 RANGE_WIDTH_2[64] = {19578,16582,12257,7906,4576,2366,1170,536,261,119,65,31,19,10,6,3,3,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,}; - -#define RANGE_OVERFLOW_TOTAL_WIDTH 65536 -#define RANGE_OVERFLOW_SHIFT 16 - -#define CODE_BITS 32 -#define TOP_VALUE ((unsigned int ) 1 << (CODE_BITS - 1)) -#define SHIFT_BITS (CODE_BITS - 9) -#define EXTRA_BITS ((CODE_BITS - 2) % 8 + 1) -#define BOTTOM_VALUE (TOP_VALUE >> 8) - -#define MODEL_ELEMENTS 64 - -/*********************************************************************************** -Construction -***********************************************************************************/ -CUnBitArray::CUnBitArray(CIO * pIO, int nVersion) -{ - CreateHelper(pIO, 16384, nVersion); - m_nFlushCounter = 0; - m_nFinalizeCounter = 0; -} - -CUnBitArray::~CUnBitArray() -{ - SAFE_ARRAY_DELETE(m_pBitArray) -} - -unsigned int CUnBitArray::DecodeValue(DECODE_VALUE_METHOD DecodeMethod, int nParam1, int nParam2) -{ - switch (DecodeMethod) - { - case DECODE_VALUE_METHOD_UNSIGNED_INT: - return DecodeValueXBits(32); - } - - return 0; -} - -void CUnBitArray::GenerateArray(int * pOutputArray, int nElements, int nBytesRequired) -{ - GenerateArrayRange(pOutputArray, nElements); -} - -__inline unsigned char CUnBitArray::GetC() -{ - unsigned char nValue = (unsigned char) (m_pBitArray[m_nCurrentBitIndex >> 5] >> (24 - (m_nCurrentBitIndex & 31))); - m_nCurrentBitIndex += 8; - return nValue; -} - -__inline int CUnBitArray::RangeDecodeFast(int nShift) -{ - while (m_RangeCoderInfo.range <= BOTTOM_VALUE) - { - m_RangeCoderInfo.buffer = (m_RangeCoderInfo.buffer << 8) | ((m_pBitArray[m_nCurrentBitIndex >> 5] >> (24 - (m_nCurrentBitIndex & 31))) & 0xFF); - m_nCurrentBitIndex += 8; - m_RangeCoderInfo.low = (m_RangeCoderInfo.low << 8) | ((m_RangeCoderInfo.buffer >> 1) & 0xFF); - m_RangeCoderInfo.range <<= 8; - } - - // decode - m_RangeCoderInfo.range = m_RangeCoderInfo.range >> nShift; - return m_RangeCoderInfo.low / m_RangeCoderInfo.range; -} - -__inline int CUnBitArray::RangeDecodeFastWithUpdate(int nShift) -{ - while (m_RangeCoderInfo.range <= BOTTOM_VALUE) - { - m_RangeCoderInfo.buffer = (m_RangeCoderInfo.buffer << 8) | ((m_pBitArray[m_nCurrentBitIndex >> 5] >> (24 - (m_nCurrentBitIndex & 31))) & 0xFF); - m_nCurrentBitIndex += 8; - m_RangeCoderInfo.low = (m_RangeCoderInfo.low << 8) | ((m_RangeCoderInfo.buffer >> 1) & 0xFF); - m_RangeCoderInfo.range <<= 8; - } - - // decode - m_RangeCoderInfo.range = m_RangeCoderInfo.range >> nShift; - int nRetVal = m_RangeCoderInfo.low / m_RangeCoderInfo.range; - m_RangeCoderInfo.low -= m_RangeCoderInfo.range * nRetVal; - return nRetVal; -} - -int CUnBitArray::DecodeValueRange(UNBIT_ARRAY_STATE & BitArrayState) -{ - // make sure there is room for the data - // this is a little slower than ensuring a huge block to start with, but it's safer - if (m_nCurrentBitIndex > m_nRefillBitThreshold) - { - FillBitArray(); - } - - int nValue = 0; - - if (m_nVersion >= 3990) - { - // figure the pivot value - int nPivotValue = max(BitArrayState.nKSum / 32, 1); - - // get the overflow - int nOverflow = 0; - { - // decode - int nRangeTotal = RangeDecodeFast(RANGE_OVERFLOW_SHIFT); - - // lookup the symbol (must be a faster way than this) - while (nRangeTotal >= RANGE_TOTAL_2[nOverflow + 1]) { nOverflow++; } - - // update - m_RangeCoderInfo.low -= m_RangeCoderInfo.range * RANGE_TOTAL_2[nOverflow]; - m_RangeCoderInfo.range = m_RangeCoderInfo.range * RANGE_WIDTH_2[nOverflow]; - - // get the working k - if (nOverflow == (MODEL_ELEMENTS - 1)) - { - nOverflow = RangeDecodeFastWithUpdate(16); - nOverflow <<= 16; - nOverflow |= RangeDecodeFastWithUpdate(16); - } - } - - // get the value - int nBase = 0; - { - int nShift = 0; - if (nPivotValue >= (1 << 16)) - { - int nPivotValueBits = 0; - while ((nPivotValue >> nPivotValueBits) > 0) { nPivotValueBits++; } - int nSplitFactor = 1 << (nPivotValueBits - 16); - - int nPivotValueA = (nPivotValue / nSplitFactor) + 1; - int nPivotValueB = nSplitFactor; - - while (m_RangeCoderInfo.range <= BOTTOM_VALUE) - { - m_RangeCoderInfo.buffer = (m_RangeCoderInfo.buffer << 8) | ((m_pBitArray[m_nCurrentBitIndex >> 5] >> (24 - (m_nCurrentBitIndex & 31))) & 0xFF); - m_nCurrentBitIndex += 8; - m_RangeCoderInfo.low = (m_RangeCoderInfo.low << 8) | ((m_RangeCoderInfo.buffer >> 1) & 0xFF); - m_RangeCoderInfo.range <<= 8; - } - m_RangeCoderInfo.range = m_RangeCoderInfo.range / nPivotValueA; - int nBaseA = m_RangeCoderInfo.low / m_RangeCoderInfo.range; - m_RangeCoderInfo.low -= m_RangeCoderInfo.range * nBaseA; - - while (m_RangeCoderInfo.range <= BOTTOM_VALUE) - { - m_RangeCoderInfo.buffer = (m_RangeCoderInfo.buffer << 8) | ((m_pBitArray[m_nCurrentBitIndex >> 5] >> (24 - (m_nCurrentBitIndex & 31))) & 0xFF); - m_nCurrentBitIndex += 8; - m_RangeCoderInfo.low = (m_RangeCoderInfo.low << 8) | ((m_RangeCoderInfo.buffer >> 1) & 0xFF); - m_RangeCoderInfo.range <<= 8; - } - m_RangeCoderInfo.range = m_RangeCoderInfo.range / nPivotValueB; - int nBaseB = m_RangeCoderInfo.low / m_RangeCoderInfo.range; - m_RangeCoderInfo.low -= m_RangeCoderInfo.range * nBaseB; - - nBase = nBaseA * nSplitFactor + nBaseB; - } - else - { - while (m_RangeCoderInfo.range <= BOTTOM_VALUE) - { - m_RangeCoderInfo.buffer = (m_RangeCoderInfo.buffer << 8) | ((m_pBitArray[m_nCurrentBitIndex >> 5] >> (24 - (m_nCurrentBitIndex & 31))) & 0xFF); - m_nCurrentBitIndex += 8; - m_RangeCoderInfo.low = (m_RangeCoderInfo.low << 8) | ((m_RangeCoderInfo.buffer >> 1) & 0xFF); - m_RangeCoderInfo.range <<= 8; - } - - // decode - m_RangeCoderInfo.range = m_RangeCoderInfo.range / nPivotValue; - int nBaseLower = m_RangeCoderInfo.low / m_RangeCoderInfo.range; - m_RangeCoderInfo.low -= m_RangeCoderInfo.range * nBaseLower; - - nBase = nBaseLower; - } - } - - // build the value - nValue = nBase + (nOverflow * nPivotValue); - } - else - { - // decode - int nRangeTotal = RangeDecodeFast(RANGE_OVERFLOW_SHIFT); - - // lookup the symbol (must be a faster way than this) - int nOverflow = 0; - while (nRangeTotal >= RANGE_TOTAL_1[nOverflow + 1]) { nOverflow++; } - - // update - m_RangeCoderInfo.low -= m_RangeCoderInfo.range * RANGE_TOTAL_1[nOverflow]; - m_RangeCoderInfo.range = m_RangeCoderInfo.range * RANGE_WIDTH_1[nOverflow]; - - // get the working k - int nTempK; - if (nOverflow == (MODEL_ELEMENTS - 1)) - { - nTempK = RangeDecodeFastWithUpdate(5); - nOverflow = 0; - } - else - { - nTempK = (BitArrayState.k < 1) ? 0 : BitArrayState.k - 1; - } - - // figure the extra bits on the left and the left value - if (nTempK <= 16 || m_nVersion < 3910) - { - nValue = RangeDecodeFastWithUpdate(nTempK); - } - else - { - int nX1 = RangeDecodeFastWithUpdate(16); - int nX2 = RangeDecodeFastWithUpdate(nTempK - 16); - nValue = nX1 | (nX2 << 16); - } - - // build the value and output it - nValue += (nOverflow << nTempK); - } - - // update nKSum - BitArrayState.nKSum += ((nValue + 1) / 2) - ((BitArrayState.nKSum + 16) >> 5); - - // update k - if (BitArrayState.nKSum < K_SUM_MIN_BOUNDARY[BitArrayState.k]) - BitArrayState.k--; - else if (BitArrayState.nKSum >= K_SUM_MIN_BOUNDARY[BitArrayState.k + 1]) - BitArrayState.k++; - - // output the value (converted to signed) - return (nValue & 1) ? (nValue >> 1) + 1 : -(nValue >> 1); -} - -void CUnBitArray::FlushState(UNBIT_ARRAY_STATE & BitArrayState) -{ - BitArrayState.k = 10; - BitArrayState.nKSum = (1 << BitArrayState.k) * 16; -} - -void CUnBitArray::FlushBitArray() -{ - // G.S.C.: Fixing a bug here. There was no check here for the buffer boundary. - // nMod is how much we will skip in AdvanceToByteBoundary + ignoring the first byte. - int nMod = m_nCurrentBitIndex % 8; - if (nMod != 0) { nMod = 8 - nMod; } - nMod += 8; - if ((m_nCurrentBitIndex + nMod) >= m_nBits) - FillBitArray(); - // G.S.C.: end - - AdvanceToByteBoundary(); - m_nCurrentBitIndex += 8; // ignore the first byte... (slows compression too much to not output this dummy byte) - m_RangeCoderInfo.buffer = GetC(); - m_RangeCoderInfo.low = m_RangeCoderInfo.buffer >> (8 - EXTRA_BITS); - m_RangeCoderInfo.range = (unsigned int) 1 << EXTRA_BITS; - - m_nRefillBitThreshold = (m_nBits - 512); -} - -void CUnBitArray::Finalize() -{ - // normalize - while (m_RangeCoderInfo.range <= BOTTOM_VALUE) - { - m_nCurrentBitIndex += 8; - m_RangeCoderInfo.range <<= 8; - } - - // used to back-pedal the last two bytes out - // this should never have been a problem because we've outputted and normalized beforehand - // but stopped doing it as of 3.96 in case it accounted for rare decompression failures - if (m_nVersion <= 3950) - m_nCurrentBitIndex -= 16; -} - -void CUnBitArray::GenerateArrayRange(int * pOutputArray, int nElements) -{ - UNBIT_ARRAY_STATE BitArrayState; - FlushState(BitArrayState); - FlushBitArray(); - - for (int z = 0; z < nElements; z++) - { - pOutputArray[z] = DecodeValueRange(BitArrayState); - } - - Finalize(); -} diff --git a/MAC_SDK/Source/MACLib/UnBitArray.h b/MAC_SDK/Source/MACLib/UnBitArray.h deleted file mode 100644 index 28f2e7d..0000000 --- a/MAC_SDK/Source/MACLib/UnBitArray.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef APE_UNBITARRAY_H -#define APE_UNBITARRAY_H - -#include "UnBitArrayBase.h" - -class IAPEDecompress; - -struct RANGE_CODER_STRUCT_DECOMPRESS -{ - unsigned int low; // low end of interval - unsigned int range; // length of interval - unsigned int buffer; // buffer for input/output -}; - -class CUnBitArray : public CUnBitArrayBase -{ -public: - - // construction/destruction - CUnBitArray(CIO * pIO, int nVersion); - ~CUnBitArray(); - - unsigned int DecodeValue(DECODE_VALUE_METHOD DecodeMethod, int nParam1 = 0, int nParam2 = 0); - - void GenerateArray(int * pOutputArray, int nElements, int nBytesRequired = -1); - - int DecodeValueRange(UNBIT_ARRAY_STATE & BitArrayState); - - void FlushState(UNBIT_ARRAY_STATE & BitArrayState); - void FlushBitArray(); - void Finalize(); - -private: - - void GenerateArrayRange(int * pOutputArray, int nElements); - - // data - int m_nFlushCounter; - int m_nFinalizeCounter; - - RANGE_CODER_STRUCT_DECOMPRESS m_RangeCoderInfo; - - uint32 m_nRefillBitThreshold; - - // functions - inline int RangeDecodeFast(int nShift); - inline int RangeDecodeFastWithUpdate(int nShift); - inline unsigned char GetC(); -}; - -#endif // #ifndef APE_UNBITARRAY_H diff --git a/MAC_SDK/Source/MACLib/UnBitArrayBase.cpp b/MAC_SDK/Source/MACLib/UnBitArrayBase.cpp deleted file mode 100644 index e819290..0000000 --- a/MAC_SDK/Source/MACLib/UnBitArrayBase.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "All.h" -#include "UnBitArrayBase.h" -#include "APEInfo.h" -#include "UnBitArray.h" -#ifdef BACKWARDS_COMPATIBILITY - #include "Old/APEDecompressOld.h" - #include "Old/UnBitArrayOld.h" -#endif - -const uint32 POWERS_OF_TWO_MINUS_ONE[33] = {0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535,131071,262143,524287,1048575,2097151,4194303,8388607,16777215,33554431,67108863,134217727,268435455,536870911,1073741823,2147483647,4294967295}; - -CUnBitArrayBase * CreateUnBitArray(IAPEDecompress * pAPEDecompress, int nVersion) -{ -#ifdef BACKWARDS_COMPATIBILITY - if (nVersion >= 3900) - return (CUnBitArrayBase * ) new CUnBitArray(GET_IO(pAPEDecompress), nVersion); - else - return (CUnBitArrayBase * ) new CUnBitArrayOld(pAPEDecompress, nVersion); -#else - return (CUnBitArrayBase * ) new CUnBitArray(GET_IO(pAPEDecompress), nVersion); -#endif -} - -void CUnBitArrayBase::AdvanceToByteBoundary() -{ - int nMod = m_nCurrentBitIndex % 8; - if (nMod != 0) { m_nCurrentBitIndex += 8 - nMod; } -} - -uint32 CUnBitArrayBase::DecodeValueXBits(uint32 nBits) -{ - // get more data if necessary - if ((m_nCurrentBitIndex + nBits) >= m_nBits) - FillBitArray(); - - // variable declares - uint32 nLeftBits = 32 - (m_nCurrentBitIndex & 31); - uint32 nBitArrayIndex = m_nCurrentBitIndex >> 5; - m_nCurrentBitIndex += nBits; - - // if their isn't an overflow to the right value, get the value and exit - if (nLeftBits >= nBits) - return (m_pBitArray[nBitArrayIndex] & (POWERS_OF_TWO_MINUS_ONE[nLeftBits])) >> (nLeftBits - nBits); - - // must get the "split" value from left and right - int nRightBits = nBits - nLeftBits; - - uint32 nLeftValue = ((m_pBitArray[nBitArrayIndex] & POWERS_OF_TWO_MINUS_ONE[nLeftBits]) << nRightBits); - uint32 nRightValue = (m_pBitArray[nBitArrayIndex + 1] >> (32 - nRightBits)); - return (nLeftValue | nRightValue); -} - -int CUnBitArrayBase::FillAndResetBitArray(int nFileLocation, int nNewBitIndex) -{ - // reset the bit index - m_nCurrentBitIndex = nNewBitIndex; - - // seek if necessary - if (nFileLocation != -1) - { - if (m_pIO->Seek(nFileLocation, FILE_BEGIN) != 0) - return ERROR_IO_READ; - } - - // read the new data into the bit array - unsigned int nBytesRead = 0; - if (m_pIO->Read(((unsigned char *) m_pBitArray), m_nBytes, &nBytesRead) != 0) - return ERROR_IO_READ; - - return 0; -} - -int CUnBitArrayBase::FillBitArray() -{ - // get the bit array index - uint32 nBitArrayIndex = m_nCurrentBitIndex >> 5; - - // move the remaining data to the front - memmove((void *) (m_pBitArray), (const void *) (m_pBitArray + nBitArrayIndex), m_nBytes - (nBitArrayIndex * 4)); - - // read the new data - int nBytesToRead = nBitArrayIndex * 4; - unsigned int nBytesRead = 0; - int nRetVal = m_pIO->Read((unsigned char *) (m_pBitArray + m_nElements - nBitArrayIndex), nBytesToRead, &nBytesRead); - - // adjust the m_Bit pointer - m_nCurrentBitIndex = m_nCurrentBitIndex & 31; - - // return - return (nRetVal == 0) ? 0 : ERROR_IO_READ; -} - -int CUnBitArrayBase::CreateHelper(CIO * pIO, int nBytes, int nVersion) -{ - // check the parameters - if ((pIO == NULL) || (nBytes <= 0)) { return ERROR_BAD_PARAMETER; } - - // save the size - m_nElements = nBytes / 4; - m_nBytes = m_nElements * 4; - m_nBits = m_nBytes * 8; - - // set the variables - m_pIO = pIO; - m_nVersion = nVersion; - m_nCurrentBitIndex = 0; - - // create the bitarray - m_pBitArray = new uint32 [m_nElements]; - - return (m_pBitArray != NULL) ? 0 : ERROR_INSUFFICIENT_MEMORY; -} diff --git a/MAC_SDK/Source/MACLib/UnBitArrayBase.h b/MAC_SDK/Source/MACLib/UnBitArrayBase.h deleted file mode 100644 index eb81e15..0000000 --- a/MAC_SDK/Source/MACLib/UnBitArrayBase.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef APE_UNBITARRAYBASE_H -#define APE_UNBITARRAYBASE_H - -class IAPEDecompress; -class CIO; - -struct UNBIT_ARRAY_STATE -{ - uint32 k; - uint32 nKSum; -}; - -enum DECODE_VALUE_METHOD -{ - DECODE_VALUE_METHOD_UNSIGNED_INT, - DECODE_VALUE_METHOD_UNSIGNED_RICE, - DECODE_VALUE_METHOD_X_BITS -}; - -class CUnBitArrayBase -{ -public: - - // virtual destructor - virtual ~CUnBitArrayBase() {} - - // functions - virtual int FillBitArray(); - virtual int FillAndResetBitArray(int nFileLocation = -1, int nNewBitIndex = 0); - - virtual void GenerateArray(int * pOutputArray, int nElements, int nBytesRequired = -1) {} - virtual unsigned int DecodeValue(DECODE_VALUE_METHOD DecodeMethod, int nParam1 = 0, int nParam2 = 0) { return 0; } - - virtual void AdvanceToByteBoundary(); - - virtual int DecodeValueRange(UNBIT_ARRAY_STATE & BitArrayState) { return 0; } - virtual void FlushState(UNBIT_ARRAY_STATE & BitArrayState) {} - virtual void FlushBitArray() {} - virtual void Finalize() {} - -protected: - - virtual int CreateHelper(CIO * pIO, int nBytes, int nVersion); - virtual uint32 DecodeValueXBits(uint32 nBits); - - uint32 m_nElements; - uint32 m_nBytes; - uint32 m_nBits; - - int m_nVersion; - CIO * m_pIO; - - uint32 m_nCurrentBitIndex; - uint32 * m_pBitArray; -}; - -CUnBitArrayBase * CreateUnBitArray(IAPEDecompress * pAPEDecompress, int nVersion); - -#endif // #ifndef APE_UNBITARRAYBASE_H diff --git a/MAC_SDK/Source/MACLib/WAVInputSource.cpp b/MAC_SDK/Source/MACLib/WAVInputSource.cpp deleted file mode 100644 index c21ae83..0000000 --- a/MAC_SDK/Source/MACLib/WAVInputSource.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#include "All.h" -#include "WAVInputSource.h" -#include IO_HEADER_FILE -#include "MACLib.h" -#include "GlobalFunctions.h" - -struct RIFF_HEADER -{ - char cRIFF[4]; // the characters 'RIFF' indicating that it's a RIFF file - unsigned long nBytes; // the number of bytes following this header -}; - -struct DATA_TYPE_ID_HEADER -{ - char cDataTypeID[4]; // should equal 'WAVE' for a WAV file -}; - -struct WAV_FORMAT_HEADER -{ - unsigned short nFormatTag; // the format of the WAV...should equal 1 for a PCM file - unsigned short nChannels; // the number of channels - unsigned long nSamplesPerSecond; // the number of samples per second - unsigned long nBytesPerSecond; // the bytes per second - unsigned short nBlockAlign; // block alignment - unsigned short nBitsPerSample; // the number of bits per sample -}; - -struct RIFF_CHUNK_HEADER -{ - char cChunkLabel[4]; // should equal "data" indicating the data chunk - unsigned long nChunkBytes; // the bytes of the chunk -}; - - -CInputSource * CreateInputSource(const wchar_t * pSourceName, WAVEFORMATEX * pwfeSource, int * pTotalBlocks, int * pHeaderBytes, int * pTerminatingBytes, int * pErrorCode) -{ - // error check the parameters - if ((pSourceName == NULL) || (wcslen(pSourceName) == 0)) - { - if (pErrorCode) *pErrorCode = ERROR_BAD_PARAMETER; - return NULL; - } - - // get the extension - const wchar_t * pExtension = &pSourceName[wcslen(pSourceName)]; - while ((pExtension > pSourceName) && (*pExtension != '.')) - pExtension--; - - // create the proper input source - if (wcsicmp(pExtension, L".wav") == 0) - { - if (pErrorCode) *pErrorCode = ERROR_SUCCESS; - return new CWAVInputSource(pSourceName, pwfeSource, pTotalBlocks, pHeaderBytes, pTerminatingBytes, pErrorCode); - } - else - { - if (pErrorCode) *pErrorCode = ERROR_INVALID_INPUT_FILE; - return NULL; - } -} - -CWAVInputSource::CWAVInputSource(CIO * pIO, WAVEFORMATEX * pwfeSource, int * pTotalBlocks, int * pHeaderBytes, int * pTerminatingBytes, int * pErrorCode) - : CInputSource(pIO, pwfeSource, pTotalBlocks, pHeaderBytes, pTerminatingBytes, pErrorCode) -{ - m_bIsValid = FALSE; - - if (pIO == NULL || pwfeSource == NULL) - { - if (pErrorCode) *pErrorCode = ERROR_BAD_PARAMETER; - return; - } - - m_spIO.Assign(pIO, FALSE, FALSE); - - int nRetVal = AnalyzeSource(); - if (nRetVal == ERROR_SUCCESS) - { - // fill in the parameters - if (pwfeSource) memcpy(pwfeSource, &m_wfeSource, sizeof(WAVEFORMATEX)); - if (pTotalBlocks) *pTotalBlocks = m_nDataBytes / m_wfeSource.nBlockAlign; - if (pHeaderBytes) *pHeaderBytes = m_nHeaderBytes; - if (pTerminatingBytes) *pTerminatingBytes = m_nTerminatingBytes; - - m_bIsValid = TRUE; - } - - if (pErrorCode) *pErrorCode = nRetVal; -} - -CWAVInputSource::CWAVInputSource(const wchar_t * pSourceName, WAVEFORMATEX * pwfeSource, int * pTotalBlocks, int * pHeaderBytes, int * pTerminatingBytes, int * pErrorCode) - : CInputSource(pSourceName, pwfeSource, pTotalBlocks, pHeaderBytes, pTerminatingBytes, pErrorCode) -{ - m_bIsValid = FALSE; - - if (pSourceName == NULL || pwfeSource == NULL) - { - if (pErrorCode) *pErrorCode = ERROR_BAD_PARAMETER; - return; - } - - m_spIO.Assign(new IO_CLASS_NAME); - if (m_spIO->Open(pSourceName) != ERROR_SUCCESS) - { - m_spIO.Delete(); - if (pErrorCode) *pErrorCode = ERROR_INVALID_INPUT_FILE; - return; - } - - int nRetVal = AnalyzeSource(); - if (nRetVal == ERROR_SUCCESS) - { - // fill in the parameters - if (pwfeSource) memcpy(pwfeSource, &m_wfeSource, sizeof(WAVEFORMATEX)); - if (pTotalBlocks) *pTotalBlocks = m_nDataBytes / m_wfeSource.nBlockAlign; - if (pHeaderBytes) *pHeaderBytes = m_nHeaderBytes; - if (pTerminatingBytes) *pTerminatingBytes = m_nTerminatingBytes; - - m_bIsValid = TRUE; - } - - if (pErrorCode) *pErrorCode = nRetVal; -} - -CWAVInputSource::~CWAVInputSource() -{ - - -} - -int CWAVInputSource::AnalyzeSource() -{ - // seek to the beginning (just in case) - m_spIO->Seek(0, FILE_BEGIN); - - // get the file size - m_nFileBytes = m_spIO->GetSize(); - - // get the RIFF header - RIFF_HEADER RIFFHeader; - RETURN_ON_ERROR(ReadSafe(m_spIO, &RIFFHeader, sizeof(RIFFHeader))) - - // make sure the RIFF header is valid - if (!(RIFFHeader.cRIFF[0] == 'R' && RIFFHeader.cRIFF[1] == 'I' && RIFFHeader.cRIFF[2] == 'F' && RIFFHeader.cRIFF[3] == 'F')) - return ERROR_INVALID_INPUT_FILE; - - // read the data type header - DATA_TYPE_ID_HEADER DataTypeIDHeader; - RETURN_ON_ERROR(ReadSafe(m_spIO, &DataTypeIDHeader, sizeof(DataTypeIDHeader))) - - // make sure it's the right data type - if (!(DataTypeIDHeader.cDataTypeID[0] == 'W' && DataTypeIDHeader.cDataTypeID[1] == 'A' && DataTypeIDHeader.cDataTypeID[2] == 'V' && DataTypeIDHeader.cDataTypeID[3] == 'E')) - return ERROR_INVALID_INPUT_FILE; - - // find the 'fmt ' chunk - RIFF_CHUNK_HEADER RIFFChunkHeader; - RETURN_ON_ERROR(ReadSafe(m_spIO, &RIFFChunkHeader, sizeof(RIFFChunkHeader))) - - while (!(RIFFChunkHeader.cChunkLabel[0] == 'f' && RIFFChunkHeader.cChunkLabel[1] == 'm' && RIFFChunkHeader.cChunkLabel[2] == 't' && RIFFChunkHeader.cChunkLabel[3] == ' ')) - { - // move the file pointer to the end of this chunk - m_spIO->Seek(RIFFChunkHeader.nChunkBytes, FILE_CURRENT); - - // check again for the data chunk - RETURN_ON_ERROR(ReadSafe(m_spIO, &RIFFChunkHeader, sizeof(RIFFChunkHeader))) - } - - // read the format info - WAV_FORMAT_HEADER WAVFormatHeader; - RETURN_ON_ERROR(ReadSafe(m_spIO, &WAVFormatHeader, sizeof(WAVFormatHeader))) - - // error check the header to see if we support it - if (WAVFormatHeader.nFormatTag != 1) - return ERROR_INVALID_INPUT_FILE; - - // copy the format information to the WAVEFORMATEX passed in - FillWaveFormatEx(&m_wfeSource, WAVFormatHeader.nSamplesPerSecond, WAVFormatHeader.nBitsPerSample, WAVFormatHeader.nChannels); - - // skip over any extra data in the header - int nWAVFormatHeaderExtra = RIFFChunkHeader.nChunkBytes - sizeof(WAVFormatHeader); - if (nWAVFormatHeaderExtra < 0) - return ERROR_INVALID_INPUT_FILE; - else - m_spIO->Seek(nWAVFormatHeaderExtra, FILE_CURRENT); - - // find the data chunk - RETURN_ON_ERROR(ReadSafe(m_spIO, &RIFFChunkHeader, sizeof(RIFFChunkHeader))) - - while (!(RIFFChunkHeader.cChunkLabel[0] == 'd' && RIFFChunkHeader.cChunkLabel[1] == 'a' && RIFFChunkHeader.cChunkLabel[2] == 't' && RIFFChunkHeader.cChunkLabel[3] == 'a')) - { - // move the file pointer to the end of this chunk - m_spIO->Seek(RIFFChunkHeader.nChunkBytes, FILE_CURRENT); - - // check again for the data chunk - RETURN_ON_ERROR(ReadSafe(m_spIO, &RIFFChunkHeader, sizeof(RIFFChunkHeader))) - } - - // we're at the data block - m_nHeaderBytes = m_spIO->GetPosition(); - m_nDataBytes = RIFFChunkHeader.nChunkBytes; - if (m_nDataBytes < 0) - m_nDataBytes = m_nFileBytes - m_nHeaderBytes; - - // make sure the data bytes is a whole number of blocks - if ((m_nDataBytes % m_wfeSource.nBlockAlign) != 0) - return ERROR_INVALID_INPUT_FILE; - - // calculate the terminating byts - m_nTerminatingBytes = m_nFileBytes - m_nDataBytes - m_nHeaderBytes; - - // we made it this far, everything must be cool - return ERROR_SUCCESS; -} - -int CWAVInputSource::GetData(unsigned char * pBuffer, int nBlocks, int * pBlocksRetrieved) -{ - if (!m_bIsValid) return ERROR_UNDEFINED; - - int nBytes = (m_wfeSource.nBlockAlign * nBlocks); - unsigned int nBytesRead = 0; - - if (m_spIO->Read(pBuffer, nBytes, &nBytesRead) != ERROR_SUCCESS) - return ERROR_IO_READ; - - if (pBlocksRetrieved) *pBlocksRetrieved = (nBytesRead / m_wfeSource.nBlockAlign); - - return ERROR_SUCCESS; -} - -int CWAVInputSource::GetHeaderData(unsigned char * pBuffer) -{ - if (!m_bIsValid) return ERROR_UNDEFINED; - - int nRetVal = ERROR_SUCCESS; - - if (m_nHeaderBytes > 0) - { - int nOriginalFileLocation = m_spIO->GetPosition(); - - m_spIO->Seek(0, FILE_BEGIN); - - unsigned int nBytesRead = 0; - int nReadRetVal = m_spIO->Read(pBuffer, m_nHeaderBytes, &nBytesRead); - - if ((nReadRetVal != ERROR_SUCCESS) || (m_nHeaderBytes != int(nBytesRead))) - { - nRetVal = ERROR_UNDEFINED; - } - - m_spIO->Seek(nOriginalFileLocation, FILE_BEGIN); - } - - return nRetVal; -} - -int CWAVInputSource::GetTerminatingData(unsigned char * pBuffer) -{ - if (!m_bIsValid) return ERROR_UNDEFINED; - - int nRetVal = ERROR_SUCCESS; - - if (m_nTerminatingBytes > 0) - { - int nOriginalFileLocation = m_spIO->GetPosition(); - - m_spIO->Seek(-m_nTerminatingBytes, FILE_END); - - unsigned int nBytesRead = 0; - int nReadRetVal = m_spIO->Read(pBuffer, m_nTerminatingBytes, &nBytesRead); - - if ((nReadRetVal != ERROR_SUCCESS) || (m_nTerminatingBytes != int(nBytesRead))) - { - nRetVal = ERROR_UNDEFINED; - } - - m_spIO->Seek(nOriginalFileLocation, FILE_BEGIN); - } - - return nRetVal; -} diff --git a/MAC_SDK/Source/MACLib/WAVInputSource.h b/MAC_SDK/Source/MACLib/WAVInputSource.h deleted file mode 100644 index 9d14813..0000000 --- a/MAC_SDK/Source/MACLib/WAVInputSource.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef APE_WAVINPUTSOURCE_H -#define APE_WAVINPUTSOURCE_H - -#include "IO.h" - -/************************************************************************************* -CInputSource - base input format class (allows multiple format support) -*************************************************************************************/ -class CInputSource -{ -public: - - // construction / destruction - CInputSource(CIO * pIO, WAVEFORMATEX * pwfeSource, int * pTotalBlocks, int * pHeaderBytes, int * pTerminatingBytes, int * pErrorCode = NULL) { } - CInputSource(const wchar_t * pSourceName, WAVEFORMATEX * pwfeSource, int * pTotalBlocks, int * pHeaderBytes, int * pTerminatingBytes, int * pErrorCode = NULL) { } - virtual ~CInputSource() { } - - // get data - virtual int GetData(unsigned char * pBuffer, int nBlocks, int * pBlocksRetrieved) = 0; - - // get header / terminating data - virtual int GetHeaderData(unsigned char * pBuffer) = 0; - virtual int GetTerminatingData(unsigned char * pBuffer) = 0; -}; - -/************************************************************************************* -CWAVInputSource - wraps working with WAV files (could be extended to any format) -*************************************************************************************/ -class CWAVInputSource : public CInputSource -{ -public: - - // construction / destruction - CWAVInputSource(CIO * pIO, WAVEFORMATEX * pwfeSource, int * pTotalBlocks, int * pHeaderBytes, int * pTerminatingBytes, int * pErrorCode = NULL); - CWAVInputSource(const wchar_t * pSourceName, WAVEFORMATEX * pwfeSource, int * pTotalBlocks, int * pHeaderBytes, int * pTerminatingBytes, int * pErrorCode = NULL); - ~CWAVInputSource(); - - // get data - int GetData(unsigned char * pBuffer, int nBlocks, int * pBlocksRetrieved); - - // get header / terminating data - int GetHeaderData(unsigned char * pBuffer); - int GetTerminatingData(unsigned char * pBuffer); - -private: - - int AnalyzeSource(); - - CSmartPtr 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 deleted file mode 100644 index 0167ab3..0000000 --- a/MAC_SDK/Source/MACLib/md5.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 deleted file mode 100644 index 63adbe7..0000000 --- a/MAC_SDK/Source/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -# -# 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 deleted file mode 100644 index 5f8c51e..0000000 --- a/MAC_SDK/Source/Readme.htm +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - -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 deleted file mode 100644 index a4a99da..0000000 --- a/MAC_SDK/Source/Shared/APEInfoDialog.cpp +++ /dev/null @@ -1,308 +0,0 @@ -#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 deleted file mode 100644 index 60a2495..0000000 --- a/MAC_SDK/Source/Shared/APEInfoDialog.h +++ /dev/null @@ -1,22 +0,0 @@ -#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 deleted file mode 100644 index 32f9a22..0000000 --- a/MAC_SDK/Source/Shared/All.h +++ /dev/null @@ -1,237 +0,0 @@ -#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 NO_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 NO_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 deleted file mode 100644 index fb4bbc6..0000000 --- a/MAC_SDK/Source/Shared/CharacterHelper.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#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 deleted file mode 100644 index 6f63a1e..0000000 --- a/MAC_SDK/Source/Shared/CharacterHelper.h +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************************* -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 deleted file mode 100644 index 7ed9ec2..0000000 --- a/MAC_SDK/Source/Shared/CircleBuffer.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#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 deleted file mode 100644 index 3d008dd..0000000 --- a/MAC_SDK/Source/Shared/CircleBuffer.h +++ /dev/null @@ -1,59 +0,0 @@ -#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 deleted file mode 100644 index 5f0b578..0000000 --- a/MAC_SDK/Source/Shared/GlobalFunctions.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#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 deleted file mode 100644 index 0928cbb..0000000 --- a/MAC_SDK/Source/Shared/GlobalFunctions.h +++ /dev/null @@ -1,21 +0,0 @@ -#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 deleted file mode 100644 index aa168ee..0000000 --- a/MAC_SDK/Source/Shared/ID3Genres.h +++ /dev/null @@ -1,27 +0,0 @@ -#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 deleted file mode 100644 index ddf46bb..0000000 --- a/MAC_SDK/Source/Shared/IO.h +++ /dev/null @@ -1,49 +0,0 @@ -#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, int fReadonly = 0) = 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 deleted file mode 100644 index e6519d7..0000000 --- a/MAC_SDK/Source/Shared/NoWindows.h +++ /dev/null @@ -1,68 +0,0 @@ -#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 deleted file mode 100644 index 0c5b8e0..0000000 --- a/MAC_SDK/Source/Shared/RollBuffer.h +++ /dev/null @@ -1,120 +0,0 @@ -#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 deleted file mode 100644 index c9bb9be..0000000 --- a/MAC_SDK/Source/Shared/SmartPtr.h +++ /dev/null @@ -1,89 +0,0 @@ -#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 deleted file mode 100644 index 5f59069..0000000 --- a/MAC_SDK/Source/Shared/StdLibFileIO.cpp +++ /dev/null @@ -1,239 +0,0 @@ -#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 -# include -# include -#else -# include -# include -# include -# include -#endif - - -#ifndef O_BINARY -# ifdef _O_BINARY -# define O_BINARY _O_BINARY -# else -# define O_BINARY 0 -# endif -#endif - -//// Binary/Low-Level-IO /////////////////////////////////////////// -// -// All file I/O is basicly handled via an ANSI file pointer (type: FILE*) in -// FILEIO-Mode 1 and via a POSIX file descriptor (type: int) in -// FILEIO-Mode 2 and 3. -// -// Some operation are only available via the POSIX interface (fcntl, setmode, -// ...) so we need a function to get the file descriptor from a file pointer. -// In FILEIO-Mode 2 and 3 this is a dummy function because we always working -// with this file descriptors. -// - -#if defined __BORLANDC__ || defined _WIN32 -# define FILENO(__fp) _fileno ((__fp)) -#elif defined __CYGWIN__ || defined __TURBOC__ || defined __unix__ || defined __EMX__ || defined _MSC_VER -# define FILENO(__fp) fileno ((__fp)) -#else -# define FILENO(__fp) fileno ((__fp)) -#endif - - -// -// If we have access to a file via file name, we can open the file with an -// additional "b" or a O_BINARY within the (f)open function to get a -// transparent untranslated data stream which is necessary for audio bitstream -// data and also for PCM data. If we are working with -// stdin/stdout/FILENO_STDIN/FILENO_STDOUT we can't open the file with this -// attributes, because the files are already open. So we need a non -// standardized sequence to switch to this mode (not necessary for Unix). -// Mostly the sequency is the same for incoming and outgoing streams, but only -// mostly so we need one for IN and one for OUT. -// Macros are called with the file pointer and you get back the untransalted file -// pointer which can be equal or different from the original. -// - -#if defined __EMX__ -# define SETBINARY_IN(__fp) (_fsetmode ( (__fp), "b" ), (__fp)) -# define SETBINARY_OUT(__fp) (_fsetmode ( (__fp), "b" ), (__fp)) -#elif defined __TURBOC__ || defined __BORLANDC__ -# define SETBINARY_IN(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) -# define SETBINARY_OUT(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) -#elif defined __CYGWIN__ -# define SETBINARY_IN(__fp) (setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) -# define SETBINARY_OUT(__fp) (setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) -#elif defined _WIN32 -# define SETBINARY_IN(__fp) (_setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) -# define SETBINARY_OUT(__fp) (_setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) -#elif defined _MSC_VER -# define SETBINARY_IN(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) -# define SETBINARY_OUT(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) -#elif defined __unix__ -# define SETBINARY_IN(__fp) (__fp) -# define SETBINARY_OUT(__fp) (__fp) -#elif 0 -# define SETBINARY_IN(__fp) (freopen ( NULL, "rb", (__fp) ), (__fp)) -# define SETBINARY_OUT(__fp) (freopen ( NULL, "wb", (__fp) ), (__fp)) -#else -# define SETBINARY_IN(__fp) (__fp) -# define SETBINARY_OUT(__fp) (__fp) -#endif - - -/////////////////////////////////////////////////////// - -CStdLibFileIO::CStdLibFileIO() -{ - memset(m_cFileName, 0, MAX_PATH); - m_bReadOnly = FALSE; - m_pFile = NULL; -} - -CStdLibFileIO::~CStdLibFileIO() -{ - Close(); -} - -int CStdLibFileIO::GetHandle() -{ - return FILENO(m_pFile); -} - -int CStdLibFileIO::Open(LPCTSTR pName) -{ - Close(); - - m_bReadOnly = FALSE; - - if (0 == strcmp(pName, "-") || 0 == strcmp(pName, "/dev/stdin")) - { - m_pFile = SETBINARY_IN(stdin); - m_bReadOnly = TRUE; // ReadOnly - } - else if (0 == strcmp (pName, "/dev/stdout")) - { - m_pFile = SETBINARY_OUT(stdout); - m_bReadOnly = FALSE; // WriteOnly - } - else - { - m_pFile = fopen(pName, "rb"); - m_bReadOnly = FALSE; // Read/Write - } - - if (!m_pFile) - return -1; - - strcpy(m_cFileName, pName); - - return 0; -} - -int CStdLibFileIO::Close() -{ - int nRetVal = -1; - - if (m_pFile != NULL) - { - nRetVal = fclose(m_pFile); - m_pFile = NULL; - } - - return nRetVal; -} - -int CStdLibFileIO::Read(void * pBuffer, unsigned int nBytesToRead, unsigned int * pBytesRead) -{ - *pBytesRead = fread(pBuffer, 1, nBytesToRead, m_pFile); - return ferror(m_pFile) ? ERROR_IO_READ : 0; -} - -int CStdLibFileIO::Write(const void * pBuffer, unsigned int nBytesToWrite, unsigned int * pBytesWritten) -{ - *pBytesWritten = fwrite(pBuffer, 1, nBytesToWrite, m_pFile); - - return (ferror(m_pFile) || (*pBytesWritten != nBytesToWrite)) ? ERROR_IO_WRITE : 0; -} - -int CStdLibFileIO::Seek(int nDistance, unsigned int nMoveMode) -{ - return fseek(m_pFile, nDistance, nMoveMode); -} - -int CStdLibFileIO::SetEOF() -{ - return ftruncate(GetHandle(), GetPosition()); -} - -int CStdLibFileIO::GetPosition() -{ - fpos_t fPosition; - - memset(&fPosition, 0, sizeof(fPosition)); - fgetpos(m_pFile, &fPosition); - return _FPOSOFF(fPosition); -} - -int CStdLibFileIO::GetSize() -{ - int nCurrentPosition = GetPosition(); - Seek(0, FILE_END); - int nLength = GetPosition(); - Seek(nCurrentPosition, FILE_BEGIN); - return nLength; -} - -int CStdLibFileIO::GetName(char * pBuffer) -{ - strcpy(pBuffer, m_cFileName); - return 0; -} - -int CStdLibFileIO::Create(const wchar_t * pName) -{ - Close(); - - if (0 == strcmp (pName, "-") || 0 == strcmp (pName, "/dev/stdout")) - { - m_pFile = SETBINARY_OUT(stdout); - m_bReadOnly = FALSE; // WriteOnly - } - else - { - m_pFile = fopen (pName, "wb"); // Read/Write - m_bReadOnly = FALSE; - } - - if (!m_pFile) - return -1; - - strcpy (m_cFileName, pName); - - return 0; -} - -int CStdLibFileIO::Delete() -{ - Close(); - return unlink (m_cFileName); // 0 success, -1 error -} - -#endif // #ifdef IO_USE_STD_LIB_FILE_IO diff --git a/MAC_SDK/Source/Shared/StdLibFileIO.h b/MAC_SDK/Source/Shared/StdLibFileIO.h deleted file mode 100644 index cf4b2b6..0000000 --- a/MAC_SDK/Source/Shared/StdLibFileIO.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifdef IO_USE_STD_LIB_FILE_IO - -#ifndef APE_STDLIBFILEIO_H -#define APE_STDLIBFILEIO_H - -#include "IO.h" - -class CStdLibFileIO : public CIO -{ -public: - - // construction / destruction - CStdLibFileIO(); - ~CStdLibFileIO(); - - // open / close - int Open(LPCTSTR pName); - int Close(); - - // read / write - int Read(void * pBuffer, unsigned int nBytesToRead, unsigned int * pBytesRead); - int Write(const void * pBuffer, unsigned int nBytesToWrite, unsigned int * pBytesWritten); - - // seek - int Seek(int nDistance, unsigned int nMoveMode); - - // other functions - int SetEOF(); - - // creation / destruction - int Create(const char * pName); - int Delete(); - - // attributes - int GetPosition(); - int GetSize(); - int GetName(char * pBuffer); - int GetHandle(); - -private: - - char m_cFileName[MAX_PATH]; - BOOL m_bReadOnly; - FILE * m_pFile; -}; - -#endif // #ifndef APE_STDLIBFILEIO_H - -#endif // #ifdef IO_USE_STD_LIB_FILE_IO - diff --git a/MAC_SDK/Source/Shared/StdString.h b/MAC_SDK/Source/Shared/StdString.h deleted file mode 100644 index a1709f5..0000000 --- a/MAC_SDK/Source/Shared/StdString.h +++ /dev/null @@ -1,3015 +0,0 @@ -// ============================================================================= -// FILE: StdString.h -// AUTHOR: Joe O'Leary (with outside help noted in comments) -// REMARKS: -// This header file declares the CStdStr template. This template derives -// the Standard C++ Library basic_string<> template and add to it the -// the following conveniences: -// - The full MFC CString set of functions (including implicit cast) -// - writing to/reading from COM IStream interfaces -// - Functional objects for use in STL algorithms -// -// From this template, we intstantiate two classes: CStdStringA and -// CStdStringW. The name "CStdString" is just a #define of one of these, -// based upone the _UNICODE macro setting -// -// This header also declares our own version of the MFC/ATL UNICODE-MBCS -// conversion macros. Our version looks exactly like the Microsoft's to -// facilitate portability. -// -// NOTE: -// If you you use this in an MFC or ATL build, you should include either -// afx.h or atlbase.h first, as appropriate. -// -// PEOPLE WHO HAVE CONTRIBUTED TO THIS CLASS: -// -// Several people have helped me iron out problems and othewise improve -// this class. OK, this is a long list but in my own defense, this code -// has undergone two major rewrites. Many of the improvements became -// necessary after I rewrote the code as a template. Others helped me -// improve the CString facade. -// -// Anyway, these people are (in chronological order): -// -// - Pete the Plumber (???) -// - Julian Selman -// - Chris (of Melbsys) -// - Dave Plummer -// - John C Sipos -// - Chris Sells -// - Nigel Nunn -// - Fan Xia -// - Matthew Williams -// - Carl Engman -// - Mark Zeren -// - Craig Watson -// - Rich Zuris -// - Karim Ratib -// - Chris Conti -// - Baptiste Lepilleur -// - Greg Pickles -// - Jim Cline -// - Jeff Kohn -// - Todd Heckel -// - Ullrich Pollähne -// - Joe Vitaterna -// - Joe Woodbury -// - Aaron (no last name) -// - Joldakowski (???) -// - Scott Hathaway -// - Eric Nitzche -// - Pablo Presedo -// -// REVISION HISTORY -// 2001-APR-27 - StreamLoad was calculating the number of BYTES in one -// case, not characters. Thanks to Pablo Presedo for this. -// -// 2001-FEB-23 - Replace() had a bug which caused infinite loops if the -// source string was empty. Fixed thanks to Eric Nitzsche. -// -// 2001-FEB-23 - Scott Hathaway was a huge help in providing me with the -// ability to build CStdString on Sun Unix systems. He -// sent me detailed build reports about what works and what -// does not. If CStdString compiles on your Unix box, you -// can thank Scott for it. -// -// 2000-DEC-29 - Joldakowski noticed one overload of Insert failed to do -// range check as CString's does. Now fixed -- thanks! -// -// 2000-NOV-07 - Aaron pointed out that I was calling static member -// functions of char_traits via a temporary. This was not -// technically wrong, but it was unnecessary and caused -// problems for poor old buggy VC5. Thanks Aaron! -// -// 2000-JUL-11 - Joe Woodbury noted that the CString::Find docs don't match -// what the CString::Find code really ends up doing. I was -// trying to match the docs. Now I match the CString code -// - Joe also caught me truncating strings for GetBuffer() calls -// when the supplied length was less than the current length. -// -// 2000-MAY-25 - Better support for STLPORT's Standard library distribution -// - Got rid of the NSP macro - it interfered with Koenig lookup -// - Thanks to Joe Woodbury for catching a TrimLeft() bug that -// I introduced in January. Empty strings were not getting -// trimmed -// -// 2000-APR-17 - Thanks to Joe Vitaterna for pointing out that ReverseFind -// is supposed to be a const function. -// -// 2000-MAR-07 - Thanks to Ullrich Pollähne for catching a range bug in one -// of the overloads of assign. -// -// 2000-FEB-01 - You can now use CStdString on the Mac with CodeWarrior! -// Thanks to Todd Heckel for helping out with this. -// -// 2000-JAN-23 - Thanks to Jim Cline for pointing out how I could make the -// Trim() function more efficient. -// - Thanks to Jeff Kohn for prompting me to find and fix a typo -// in one of the addition operators that takes _bstr_t. -// - Got rid of the .CPP file - you only need StdString.h now! -// -// 1999-DEC-22 - Thanks to Greg Pickles for helping me identify a problem -// with my implementation of CStdString::FormatV in which -// resulting string might not be properly NULL terminated. -// -// 1999-DEC-06 - Chris Conti pointed yet another basic_string<> assignment -// bug that MS has not fixed. CStdString did nothing to fix -// it either but it does now! The bug was: create a string -// longer than 31 characters, get a pointer to it (via c_str()) -// and then assign that pointer to the original string object. -// The resulting string would be empty. Not with CStdString! -// -// 1999-OCT-06 - BufferSet was erasing the string even when it was merely -// supposed to shrink it. Fixed. Thanks to Chris Conti. -// - Some of the Q172398 fixes were not checking for assignment- -// to-self. Fixed. Thanks to Baptiste Lepilleur. -// -// 1999-AUG-20 - Improved Load() function to be more efficient by using -// SizeOfResource(). Thanks to Rich Zuris for this. -// - Corrected resource ID constructor, again thanks to Rich. -// - Fixed a bug that occurred with UNICODE characters above -// the first 255 ANSI ones. Thanks to Craig Watson. -// - Added missing overloads of TrimLeft() and TrimRight(). -// Thanks to Karim Ratib for pointing them out -// -// 1999-JUL-21 - Made all calls to GetBuf() with no args check length first. -// -// 1999-JUL-10 - Improved MFC/ATL independence of conversion macros -// - Added SS_NO_REFCOUNT macro to allow you to disable any -// reference-counting your basic_string<> impl. may do. -// - Improved ReleaseBuffer() to be as forgiving as CString. -// Thanks for Fan Xia for helping me find this and to -// Matthew Williams for pointing it out directly. -// -// 1999-JUL-06 - Thanks to Nigel Nunn for catching a very sneaky bug in -// ToLower/ToUpper. They should call GetBuf() instead of -// data() in order to ensure the changed string buffer is not -// reference-counted (in those implementations that refcount). -// -// 1999-JUL-01 - Added a true CString facade. Now you can use CStdString as -// a drop-in replacement for CString. If you find this useful, -// you can thank Chris Sells for finally convincing me to give -// in and implement it. -// - Changed operators << and >> (for MFC CArchive) to serialize -// EXACTLY as CString's do. So now you can send a CString out -// to a CArchive and later read it in as a CStdString. I have -// no idea why you would want to do this but you can. -// -// 1999-JUN-21 - Changed the CStdString class into the CStdStr template. -// - Fixed FormatV() to correctly decrement the loop counter. -// This was harmless bug but a bug nevertheless. Thanks to -// Chris (of Melbsys) for pointing it out -// - Changed Format() to try a normal stack-based array before -// using to _alloca(). -// - Updated the text conversion macros to properly use code -// pages and to fit in better in MFC/ATL builds. In other -// words, I copied Microsoft's conversion stuff again. -// - Added equivalents of CString::GetBuffer, GetBufferSetLength -// - new sscpy() replacement of CStdString::CopyString() -// - a Trim() function that combines TrimRight() and TrimLeft(). -// -// 1999-MAR-13 - Corrected the "NotSpace" functional object to use _istpace() -// instead of _isspace() Thanks to Dave Plummer for this. -// -// 1999-FEB-26 - Removed errant line (left over from testing) that #defined -// _MFC_VER. Thanks to John C Sipos for noticing this. -// -// 1999-FEB-03 - Fixed a bug in a rarely-used overload of operator+() that -// caused infinite recursion and stack overflow -// - Added member functions to simplify the process of -// persisting CStdStrings to/from DCOM IStream interfaces -// - Added functional objects (e.g. StdStringLessNoCase) that -// allow CStdStrings to be used as keys STL map objects with -// case-insensitive comparison -// - Added array indexing operators (i.e. operator[]). I -// originally assumed that these were unnecessary and would be -// inherited from basic_string. However, without them, Visual -// C++ complains about ambiguous overloads when you try to use -// them. Thanks to Julian Selman to pointing this out. -// -// 1998-FEB-?? - Added overloads of assign() function to completely account -// for Q172398 bug. Thanks to "Pete the Plumber" for this -// -// 1998-FEB-?? - Initial submission -// -// COPYRIGHT: -// 1999 Joseph M. O'Leary. This code is free. Use it anywhere you want. -// Rewrite it, restructure it, whatever. Please don't blame me if it makes -// your $30 billion dollar satellite explode in orbit. If you redistribute -// it in any form, I'd appreciate it if you would leave this notice here. -// -// If you find any bugs, please let me know: -// -// jmoleary@earthlink.net -// http://home.earthlink.net/~jmoleary -// ============================================================================= - -// Avoid multiple inclusion the VC++ way, -// Turn off browser references -// Turn off unavoidable compiler warnings - -#if defined(_MSC_VER) && (_MSC_VER > 1100) - #pragma once - #pragma component(browser, off, references, "CStdString") - #pragma warning (disable : 4290) // C++ Exception Specification ignored - #pragma warning (disable : 4127) // Conditional expression is constant - #pragma warning (disable : 4097) // typedef name used as synonym for class name -#endif - -#ifndef STDSTRING_H -#define STDSTRING_H - -// MACRO: SS_NO_REFCOUNT: -// turns off reference counting at the assignment level -// I define this by default. comment it out if you don't want it. - -#define SS_NO_REFCOUNT - -// In non-Visual C++ and/or non-Win32 builds, we can't use some cool stuff. - -#if !defined(_MSC_VER) || !defined(_WIN32) - #define SS_ANSI -#endif - -// Avoid legacy code screw up: if _UNICODE is defined, UNICODE must be as well - -#if defined (_UNICODE) && !defined (UNICODE) - #define UNICODE -#endif -#if defined (UNICODE) && !defined (_UNICODE) - #define _UNICODE -#endif - -// ----------------------------------------------------------------------------- -// MIN and MAX. The Standard C++ template versions go by so many names (at -// at least in the MS implementation) that you never know what's available -// ----------------------------------------------------------------------------- -template -inline const Type& SSMIN(const Type& arg1, const Type& arg2) -{ - return arg2 < arg1 ? arg2 : arg1; -} -template -inline const Type& SSMAX(const Type& arg1, const Type& arg2) -{ - return arg2 > arg1 ? arg2 : arg1; -} - -// If they have not #included W32Base.h (part of my W32 utility library) then -// we need to define some stuff. Otherwise, this is all defined there. - -#if !defined(W32BASE_H) - - // If they want us to use only standard C++ stuff (no Win32 stuff) - - #ifdef SS_ANSI - - // On non-Win32 platforms, there is no TCHAR.H so define what we need - - #ifndef _WIN32 - - typedef const char* PCSTR; - typedef char* PSTR; - typedef const wchar_t* PCWSTR; - typedef wchar_t* PWSTR; - #ifdef UNICODE - typedef wchar_t TCHAR; - #else - typedef char TCHAR; - #endif - typedef wchar_t OLECHAR; - - #else - - #include - #include - #ifndef STRICT - #define STRICT - #endif - - #endif // #ifndef _WIN32 - - - // Make sure ASSERT and verify are defined in an ANSI fashion - - #ifndef ASSERT - #include - #define ASSERT(f) assert((f)) - #endif - #ifndef VERIFY - #ifdef _DEBUG - #define VERIFY(x) ASSERT((x)) - #else - #define VERIFY(x) x - #endif - #endif - - #else // #ifdef SS_ANSI - - #include - #include - #ifndef STRICT - #define STRICT - #endif - - // Make sure ASSERT and verify are defined - - #ifndef ASSERT - #include - #define ASSERT(f) _ASSERTE((f)) - #endif - #ifndef VERIFY - #ifdef _DEBUG - #define VERIFY(x) ASSERT((x)) - #else - #define VERIFY(x) x - #endif - #endif - - #endif // #ifdef SS_ANSI - - #ifndef UNUSED - #define UNUSED(x) x - #endif - -#endif // #ifndef W32BASE_H - -// Standard headers needed - -#include // basic_string -#include // for_each, etc. -#include // for StdStringLessNoCase, et al -#include // for various facets - -// If this is a recent enough version of VC include comdef.h, so we can write -// member functions to deal with COM types & compiler support classes e.g. _bstr_t - -#if defined (_MSC_VER) && (_MSC_VER >= 1100) - #include - #define SS_INC_COMDEF // signal that we #included MS comdef.h file - #define STDSTRING_INC_COMDEF - #define SS_NOTHROW __declspec(nothrow) -#else - #define SS_NOTHROW -#endif - -#ifndef TRACE - #define TRACE_DEFINED_HERE - #define TRACE -#endif - -// Microsoft defines PCSTR, PCWSTR, etc, but no PCTSTR. I hate to use the -// versions with the "L" in front of them because that's a leftover from Win 16 -// days, even though it evaluates to the same thing. Therefore, Define a PCSTR -// as an LPCTSTR. - -#if !defined(PCTSTR) && !defined(PCTSTR_DEFINED) - typedef const TCHAR* PCTSTR; - #define PCTSTR_DEFINED -#endif - -#if !defined(PCOLESTR) && !defined(PCOLESTR_DEFINED) - typedef const OLECHAR* PCOLESTR; - #define PCOLESTR_DEFINED -#endif - -#if !defined(POLESTR) && !defined(POLESTR_DEFINED) - typedef OLECHAR* POLESTR; - #define POLESTR_DEFINED -#endif - -#if !defined(PCUSTR) && !defined(PCUSTR_DEFINED) - typedef const unsigned char* PCUSTR; - typedef unsigned char* PUSTR; - #define PCUSTR_DEFINED -#endif - -// SS_USE_FACET macro and why we need it: -// -// Since I'm a good little Standard C++ programmer, I use locales. Thus, I -// need to make use of the use_facet<> template function here. Unfortunately, -// this need is complicated by the fact the MS' implementation of the Standard -// C++ Library has a non-standard version of use_facet that takes more -// arguments than the standard dictates. Since I'm trying to write CStdString -// to work with any version of the Standard library, this presents a problem. -// -// The upshot of this is that I can't do 'use_facet' directly. The MS' docs -// tell me that I have to use a macro, _USE() instead. Since _USE obviously -// won't be available in other implementations, this means that I have to write -// my OWN macro -- SS_USE_FACET -- that evaluates either to _USE or to the -// standard, use_facet. -// -// If you are having trouble with the SS_USE_FACET macro, in your implementation -// of the Standard C++ Library, you can define your own version of SS_USE_FACET. -#ifndef schMSG - #define schSTR(x) #x - #define schSTR2(x) schSTR(x) - #define schMSG(desc) message(__FILE__ "(" schSTR2(__LINE__) "):" #desc) -#endif - -#ifndef SS_USE_FACET - // STLPort #defines a macro (__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) for - // all MSVC builds, erroneously in my opinion. It causes problems for - // my SS_ANSI builds. In my code, I always comment out that line. You'll - // find it in \stlport\config\stl_msvc.h - #if defined(__SGI_STL_PORT) && (__SGI_STL_PORT >= 0x400 ) - #if defined(__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) && defined(_MSC_VER) - #ifdef SS_ANSI - #pragma schMSG(__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS defined!!) - #endif - #endif - #define SS_USE_FACET(loc, fac) std::use_facet(loc) - #elif defined(_MSC_VER ) - #define SS_USE_FACET(loc, fac) _USE(loc, fac) - - // ...and - #elif defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) - #define SS_USE_FACET(loc, fac) std::use_facet(loc, (fac*)0) - #else - #define SS_USE_FACET(loc, fac) std::use_facet(loc) - #endif -#endif - -// ============================================================================= -// UNICODE/MBCS conversion macros. Made to work just like the MFC/ATL ones. -// ============================================================================= - -// First define the conversion helper functions. We define these regardless of -// any preprocessor macro settings since their names won't collide. - -#ifdef SS_ANSI // Are we doing things the standard, non-Win32 way?... - - typedef std::codecvt SSCodeCvt; - - // Not sure if we need all these headers. I believe ANSI says we do. - - #include - #include - #include - #ifndef va_start - #include - #endif - - // StdCodeCvt - made to look like Win32 functions WideCharToMultiByte annd - // MultiByteToWideChar but uses locales in SS_ANSI builds - inline PWSTR StdCodeCvt(PWSTR pW, PCSTR pA, int nChars, - const std::locale& loc=std::locale()) - { - ASSERT(0 != pA); - ASSERT(0 != pW); - pW[0] = '\0'; - PCSTR pBadA = 0; - PWSTR pBadW = 0; - SSCodeCvt::result res = SSCodeCvt::ok; - const SSCodeCvt& conv = SS_USE_FACET(loc, SSCodeCvt); - SSCodeCvt::state_type st= { 0 }; - res = conv.in(st, - pA, pA + nChars, pBadA, - pW, pW + nChars, pBadW); - ASSERT(SSCodeCvt::ok == res); - return pW; - } - inline PWSTR StdCodeCvt(PWSTR pW, PCUSTR pA, int nChars, - const std::locale& loc=std::locale()) - { - return StdCodeCvt(pW, (PCSTR)pA, nChars, loc); - } - - inline PSTR StdCodeCvt(PSTR pA, PCWSTR pW, int nChars, - const std::locale& loc=std::locale()) - { - ASSERT(0 != pA); - ASSERT(0 != pW); - pA[0] = '\0'; - PSTR pBadA = 0; - PCWSTR pBadW = 0; - SSCodeCvt::result res = SSCodeCvt::ok; - const SSCodeCvt& conv = SS_USE_FACET(loc, SSCodeCvt); - SSCodeCvt::state_type st= { 0 }; - res = conv.out(st, - pW, pW + nChars, pBadW, - pA, pA + nChars, pBadA); - ASSERT(SSCodeCvt::ok == res); - return pA; - } - inline PUSTR StdCodeCvt(PUSTR pA, PCWSTR pW, int nChars, - const std::locale& loc=std::locale()) - { - return (PUSTR)StdCodeCvt((PSTR)pA, pW, nChars, loc); - } - -#else // ...or are we doing things assuming win32 and Visual C++? - - #include // needed for _alloca - - inline PWSTR StdCodeCvt(PWSTR pW, PCSTR pA, int nChars, UINT acp=CP_ACP) - { - ASSERT(0 != pA); - ASSERT(0 != pW); - pW[0] = '\0'; - MultiByteToWideChar(acp, 0, pA, -1, pW, nChars); - return pW; - } - inline PWSTR StdCodeCvt(PWSTR pW, PCUSTR pA, int nChars, UINT acp=CP_ACP) - { - return StdCodeCvt(pW, (PCSTR)pA, nChars, acp); - } - - inline PSTR StdCodeCvt(PSTR pA, PCWSTR pW, int nChars, UINT acp=CP_ACP) - { - ASSERT(0 != pA); - ASSERT(0 != pW); - pA[0] = '\0'; - WideCharToMultiByte(acp, 0, pW, -1, pA, nChars, 0, 0); - return pA; - } - inline PUSTR StdCodeCvt(PUSTR pA, PCWSTR pW, int nChars, UINT acp=CP_ACP) - { - return (PUSTR)StdCodeCvt((PSTR)pA, pW, nChars, acp); - } - - // Define our conversion macros to look exactly like Microsoft's to - // facilitate using this stuff both with and without MFC/ATL - - #ifdef _CONVERSION_USES_THREAD_LOCALE - #ifndef _DEBUG - #define SSCVT int _cvt; _cvt; UINT _acp=GetACP(); \ - _acp; PCWSTR _pw; _pw; PCSTR _pa; _pa - #else - #define SSCVT int _cvt = 0; _cvt; UINT _acp=GetACP();\ - _acp; PCWSTR _pw=0; _pw; PCSTR _pa=0; _pa - #endif - #else - #ifndef _DEBUG - #define SSCVT int _cvt; _cvt; UINT _acp=CP_ACP; _acp;\ - PCWSTR _pw; _pw; PCSTR _pa; _pa - #else - #define SSCVT int _cvt = 0; _cvt; UINT _acp=CP_ACP; \ - _acp; PCWSTR _pw=0; _pw; PCSTR _pa=0; _pa - #endif - #endif - - #ifdef _CONVERSION_USES_THREAD_LOCALE - #define SSA2W(pa) (\ - ((_pa = pa) == 0) ? 0 : (\ - _cvt = (strlen(_pa)+1),\ - StdCodeCvt((PWSTR) _alloca(_cvt*2), _pa, _cvt, _acp))) - #define SSW2A(pw) (\ - ((_pw = pw) == 0) ? 0 : (\ - _cvt = (wcslen(_pw)+1)*2,\ - StdW2AHelper((LPSTR) _alloca(_cvt), _pw, _cvt, _acp))) - #else - #define SSA2W(pa) (\ - ((_pa = pa) == 0) ? 0 : (\ - _cvt = (strlen(_pa)+1),\ - StdCodeCvt((PWSTR) _alloca(_cvt*2), _pa, _cvt))) - #define SSW2A(pw) (\ - ((_pw = pw) == 0) ? 0 : (\ - _cvt = (wcslen(_pw)+1)*2,\ - StdCodeCvt((LPSTR) _alloca(_cvt), _pw, _cvt))) - #endif - - #define SSA2CW(pa) ((PCWSTR)SSA2W((pa))) - #define SSW2CA(pw) ((PCSTR)SSW2A((pw))) - - #ifdef UNICODE - #define SST2A SSW2A - #define SSA2T SSA2W - #define SST2CA SSW2CA - #define SSA2CT SSA2CW - inline PWSTR SST2W(PTSTR p) { return p; } - inline PTSTR SSW2T(PWSTR p) { return p; } - inline PCWSTR SST2CW(PCTSTR p) { return p; } - inline PCTSTR SSW2CT(PCWSTR p) { return p; } - #else - #define SST2W SSA2W - #define SSW2T SSW2A - #define SST2CW SSA2CW - #define SSW2CT SSW2CA - inline PSTR SST2A(PTSTR p) { return p; } - inline PTSTR SSA2T(PSTR p) { return p; } - inline PCSTR SST2CA(PCTSTR p) { return p; } - inline PCTSTR SSA2CT(PCSTR p) { return p; } - #endif // #ifdef UNICODE - - #if defined(UNICODE) - // in these cases the default (TCHAR) is the same as OLECHAR - inline PCOLESTR SST2COLE(PCTSTR p) { return p; } - inline PCTSTR SSOLE2CT(PCOLESTR p) { return p; } - inline POLESTR SST2OLE(PTSTR p) { return p; } - inline PTSTR SSOLE2T(POLESTR p) { return p; } - #elif defined(OLE2ANSI) - // in these cases the default (TCHAR) is the same as OLECHAR - inline PCOLESTR SST2COLE(PCTSTR p) { return p; } - inline PCTSTR SSOLE2CT(PCOLESTR p) { return p; } - inline POLESTR SST2OLE(PTSTR p) { return p; } - inline PTSTR SSOLE2T(POLESTR p) { return p; } - #else - //CharNextW doesn't work on Win95 so we use this - #define SST2COLE(pa) SSA2CW((pa)) - #define SST2OLE(pa) SSA2W((pa)) - #define SSOLE2CT(po) SSW2CA((po)) - #define SSOLE2T(po) SSW2A((po)) - #endif - - #ifdef OLE2ANSI - #define SSW2OLE SSW2A - #define SSOLE2W SSA2W - #define SSW2COLE SSW2CA - #define SSOLE2CW SSA2CW - inline POLESTR SSA2OLE(PSTR p) { return p; } - inline PSTR SSOLE2A(POLESTR p) { return p; } - inline PCOLESTR SSA2COLE(PCSTR p) { return p; } - inline PCSTR SSOLE2CA(PCOLESTR p){ return p; } - #else - #define SSA2OLE SSA2W - #define SSOLE2A SSW2A - #define SSA2COLE SSA2CW - #define SSOLE2CA SSW2CA - inline POLESTR SSW2OLE(PWSTR p) { return p; } - inline PWSTR SSOLE2W(POLESTR p) { return p; } - inline PCOLESTR SSW2COLE(PCWSTR p) { return p; } - inline PCWSTR SSOLE2CW(PCOLESTR p){ return p; } - #endif - - // Above we've defined macros that look like MS' but all have - // an 'SS' prefix. Now we need the real macros. We'll either - // get them from the macros above or from MFC/ATL. If - // SS_NO_CONVERSION is #defined, we'll forgo them - - #ifndef SS_NO_CONVERSION - - #if defined (USES_CONVERSION) - - #define _NO_STDCONVERSION // just to be consistent - - #else - - #ifdef _MFC_VER - - #include - #define _NO_STDCONVERSION // just to be consistent - - #else - - #define USES_CONVERSION SSCVT - #define A2CW SSA2CW - #define W2CA SSW2CA - #define T2A SST2A - #define A2T SSA2T - #define T2W SST2W - #define W2T SSW2T - #define T2CA SST2CA - #define A2CT SSA2CT - #define T2CW SST2CW - #define W2CT SSW2CT - #define ocslen sslen - #define ocscpy sscpy - #define T2COLE SST2COLE - #define OLE2CT SSOLE2CT - #define T2OLE SST2COLE - #define OLE2T SSOLE2CT - #define A2OLE SSA2OLE - #define OLE2A SSOLE2A - #define W2OLE SSW2OLE - #define OLE2W SSOLE2W - #define A2COLE SSA2COLE - #define OLE2CA SSOLE2CA - #define W2COLE SSW2COLE - #define OLE2CW SSOLE2CW - - #endif // #ifdef _MFC_VER - #endif // #ifndef USES_CONVERSION - #endif // #ifndef SS_NO_CONVERSION - - // Define ostring - generic name for std::basic_string - - #if !defined(ostring) && !defined(OSTRING_DEFINED) - typedef std::basic_string ostring; - #define OSTRING_DEFINED - #endif - -#endif // #ifndef SS_ANSI - -// StdCodeCvt when there's no conversion to be done -inline PSTR StdCodeCvt(PSTR pDst, PCSTR pSrc, int nChars) -{ - pDst[0] = '\0'; - std::char_traits::copy(pDst, pSrc, nChars); - if ( nChars > 0 ) - pDst[nChars] = '\0'; - - return pDst; -} -inline PSTR StdCodeCvt(PSTR pDst, PCUSTR pSrc, int nChars) -{ - return StdCodeCvt(pDst, (PCSTR)pSrc, nChars); -} -inline PUSTR StdCodeCvt(PUSTR pDst, PCSTR pSrc, int nChars) -{ - return (PUSTR)StdCodeCvt((PSTR)pDst, pSrc, nChars); -} - -inline PWSTR StdCodeCvt(PWSTR pDst, PCWSTR pSrc, int nChars) -{ - pDst[0] = '\0'; - std::char_traits::copy(pDst, pSrc, nChars); - if ( nChars > 0 ) - pDst[nChars] = '\0'; - - return pDst; -} - - -// Define tstring -- generic name for std::basic_string - -#if !defined(tstring) && !defined(TSTRING_DEFINED) - typedef std::basic_string tstring; - #define TSTRING_DEFINED -#endif - -// a very shorthand way of applying the fix for KB problem Q172398 -// (basic_string assignment bug) - -#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) - #define Q172398(x) (x).erase() -#else - #define Q172398(x) -#endif - -// ============================================================================= -// INLINE FUNCTIONS ON WHICH CSTDSTRING RELIES -// -// Usually for generic text mapping, we rely on preprocessor macro definitions -// to map to string functions. However the CStdStr<> template cannot use -// macro-based generic text mappings because its character types do not get -// resolved until template processing which comes AFTER macro processing. In -// other words, UNICODE is of little help to us in the CStdStr template -// -// Therefore, to keep the CStdStr declaration simple, we have these inline -// functions. The template calls them often. Since they are inline (and NOT -// exported when this is built as a DLL), they will probably be resolved away -// to nothing. -// -// Without these functions, the CStdStr<> template would probably have to broken -// out into two, almost identical classes. Either that or it would be a huge, -// convoluted mess, with tons of "if" statements all over the place checking the -// size of template parameter CT. -// -// In several cases, you will see two versions of each function. One version is -// the more portable, standard way of doing things, while the other is the -// non-standard, but often significantly faster Visual C++ way. -// ============================================================================= - -// If they defined SS_NO_REFCOUNT, then we must convert all assignments - -#ifdef SS_NO_REFCOUNT - #define SSREF(x) (x).c_str() -#else - #define SSREF(x) (x) -#endif - -// ----------------------------------------------------------------------------- -// sslen: strlen/wcslen wrappers -// ----------------------------------------------------------------------------- -template inline int sslen(const CT* pT) -{ - return 0 == pT ? 0 : std::char_traits::length(pT); -} -inline SS_NOTHROW int sslen(const std::string& s) -{ - return s.length(); -} -inline SS_NOTHROW int sslen(const std::wstring& s) -{ - return s.length(); -} - - -// ----------------------------------------------------------------------------- -// ssasn: assignment functions -- assign "sSrc" to "sDst" -// ----------------------------------------------------------------------------- -typedef std::string::size_type SS_SIZETYPE; // just for shorthand, really -typedef std::string::pointer SS_PTRTYPE; -typedef std::wstring::size_type SW_SIZETYPE; -typedef std::wstring::pointer SW_PTRTYPE; - -inline void ssasn(std::string& sDst, const std::string& sSrc) -{ - if ( sDst.c_str() != sSrc.c_str() ) - { - sDst.erase(); - sDst.assign(SSREF(sSrc)); - } -} -inline void ssasn(std::string& sDst, PCSTR pA) -{ - // Watch out for NULLs, as always. - - if ( 0 == pA ) - { - sDst.erase(); - } - - // If pA actually points to part of sDst, we must NOT erase(), but - // rather take a substring - - else if ( pA >= sDst.c_str() && pA <= sDst.c_str() + sDst.size() ) - { - sDst =sDst.substr(static_cast(pA-sDst.c_str())); - } - - // Otherwise (most cases) apply the assignment bug fix, if applicable - // and do the assignment - - else - { - Q172398(sDst); - sDst.assign(pA); - } -} -inline void ssasn(std::string& sDst, const std::wstring& sSrc) -{ -#ifdef SS_ANSI - int nLen = sSrc.size(); - sDst.resize(0); - sDst.resize(nLen); - StdCodeCvt(const_cast(sDst.data()), sSrc.c_str(), nLen); -#else - SSCVT; - sDst.assign(SSW2CA(sSrc.c_str())); -#endif -} -inline void ssasn(std::string& sDst, PCWSTR pW) -{ -#ifdef SS_ANSI - int nLen = sslen(pW); - sDst.resize(0); - sDst.resize(nLen); - StdCodeCvt(const_cast(sDst.data()), pW, nLen); -#else - SSCVT; - sDst.assign(pW ? SSW2CA(pW) : ""); -#endif -} -inline void ssasn(std::string& sDst, const int nNull) -{ - UNUSED(nNull); - ASSERT(nNull==0); - sDst.assign(""); -} -inline void ssasn(std::wstring& sDst, const std::wstring& sSrc) -{ - if ( sDst.c_str() != sSrc.c_str() ) - { - sDst.erase(); - sDst.assign(SSREF(sSrc)); - } -} -inline void ssasn(std::wstring& sDst, PCWSTR pW) -{ - // Watch out for NULLs, as always. - - if ( 0 == pW ) - { - sDst.erase(); - } - - // If pW actually points to part of sDst, we must NOT erase(), but - // rather take a substring - - else if ( pW >= sDst.c_str() && pW <= sDst.c_str() + sDst.size() ) - { - sDst = sDst.substr(static_cast(pW-sDst.c_str())); - } - - // Otherwise (most cases) apply the assignment bug fix, if applicable - // and do the assignment - - else - { - Q172398(sDst); - sDst.assign(pW); - } -} -#undef StrSizeType -inline void ssasn(std::wstring& sDst, const std::string& sSrc) -{ -#ifdef SS_ANSI - int nLen = sSrc.size(); - sDst.resize(0); - sDst.resize(nLen); - StdCodeCvt(const_cast(sDst.data()), sSrc.c_str(), nLen); -#else - SSCVT; - sDst.assign(SSA2CW(sSrc.c_str())); -#endif -} -inline void ssasn(std::wstring& sDst, PCSTR pA) -{ -#ifdef SS_ANSI - int nLen = sslen(pA); - sDst.resize(0); - sDst.resize(nLen); - StdCodeCvt(const_cast(sDst.data()), pA, nLen); -#else - SSCVT; - sDst.assign(pA ? SSA2CW(pA) : L""); -#endif -} -inline void ssasn(std::wstring& sDst, const int nNull) -{ - UNUSED(nNull); - ASSERT(nNull==0); - sDst.assign(L""); -} - - -// ----------------------------------------------------------------------------- -// ssadd: string object concatenation -- add second argument to first -// ----------------------------------------------------------------------------- -inline void ssadd(std::string& sDst, const std::wstring& sSrc) -{ -#ifdef SS_ANSI - int nLen = sSrc.size(); - sDst.resize(sDst.size() + nLen); - StdCodeCvt(const_cast(sDst.data()+nLen), sSrc.c_str(), nLen); -#else - SSCVT; - sDst.append(SSW2CA(sSrc.c_str())); -#endif -} -inline void ssadd(std::string& sDst, const std::string& sSrc) -{ - sDst.append(sSrc.c_str()); -} -inline void ssadd(std::string& sDst, PCWSTR pW) -{ -#ifdef SS_ANSI - int nLen = sslen(pW); - sDst.resize(sDst.size() + nLen); - StdCodeCvt(const_cast(sDst.data()+nLen), pW, nLen); -#else - SSCVT; - if ( 0 != pW ) - sDst.append(SSW2CA(pW)); -#endif -} -inline void ssadd(std::string& sDst, PCSTR pA) -{ - if ( pA ) - sDst.append(pA); -} -inline void ssadd(std::wstring& sDst, const std::wstring& sSrc) -{ - sDst.append(sSrc.c_str()); -} -inline void ssadd(std::wstring& sDst, const std::string& sSrc) -{ -#ifdef SS_ANSI - int nLen = sSrc.size(); - sDst.resize(sDst.size() + nLen); - StdCodeCvt(const_cast(sDst.data()+nLen), sSrc.c_str(), nLen); -#else - SSCVT; - sDst.append(SSA2CW(sSrc.c_str())); -#endif -} -inline void ssadd(std::wstring& sDst, PCSTR pA) -{ -#ifdef SS_ANSI - int nLen = sslen(pA); - sDst.resize(sDst.size() + nLen); - StdCodeCvt(const_cast(sDst.data()+nLen), pA, nLen); -#else - SSCVT; - if ( 0 != pA ) - sDst.append(SSA2CW(pA)); -#endif -} -inline void ssadd(std::wstring& sDst, PCWSTR pW) -{ - if ( pW ) - sDst.append(pW); -} - - -// ----------------------------------------------------------------------------- -// ssicmp: comparison (case insensitive ) -// ----------------------------------------------------------------------------- -#ifdef SS_ANSI - template - inline int ssicmp(const CT* pA1, const CT* pA2) - { - std::locale loc; - const std::ctype& ct = SS_USE_FACET(loc, std::ctype); - CT f; - CT l; - - do - { - f = ct.tolower(*(pA1++)); - l = ct.tolower(*(pA2++)); - } while ( (f) && (f == l) ); - - return (int)(f - l); - } -#else - #ifdef _MBCS - inline long sscmp(PCSTR pA1, PCSTR pA2) - { - return _mbscmp((PCUSTR)pA1, (PCUSTR)pA2); - } - inline long ssicmp(PCSTR pA1, PCSTR pA2) - { - return _mbsicmp((PCUSTR)pA1, (PCUSTR)pA2); - } - #else - inline long sscmp(PCSTR pA1, PCSTR pA2) - { - return strcmp(pA1, pA2); - } - inline long ssicmp(PCSTR pA1, PCSTR pA2) - { - return _stricmp(pA1, pA2); - } - #endif - inline long sscmp(PCWSTR pW1, PCWSTR pW2) - { - return wcscmp(pW1, pW2); - } - inline long ssicmp(PCWSTR pW1, PCWSTR pW2) - { - return _wcsicmp(pW1, pW2); - } -#endif - -// ----------------------------------------------------------------------------- -// ssupr/sslwr: Uppercase/Lowercase conversion functions -// ----------------------------------------------------------------------------- -#ifdef SS_ANSI - template - inline void sslwr(CT* pT, size_t nLen) - { - SS_USE_FACET(std::locale(), std::ctype).tolower(pT, pT+nLen); - } - template - inline void ssupr(CT* pT, size_t nLen) - { - SS_USE_FACET(std::locale(), std::ctype).toupper(pT, pT+nLen); - } -#else // #else we must be on Win32 - #ifdef _MBCS - inline void ssupr(PSTR pA, size_t /*nLen*/) - { - _mbsupr((PUSTR)pA); - } - inline void sslwr(PSTR pA, size_t /*nLen*/) - { - _mbslwr((PUSTR)pA); - } - #else - inline void ssupr(PSTR pA, size_t /*nLen*/) - { - _strupr(pA); - } - inline void sslwr(PSTR pA, size_t /*nLen*/) - { - _strlwr(pA); - } - #endif - inline void ssupr(PWSTR pW, size_t /*nLen*/) - { - _wcsupr(pW); - } - inline void sslwr(PWSTR pW, size_t /*nLen*/) - { - _wcslwr(pW); - } -#endif // #ifdef SS_ANSI - -// ----------------------------------------------------------------------------- -// vsprintf/vswprintf or _vsnprintf/_vsnwprintf equivalents. In standard -// builds we can't use _vsnprintf/_vsnwsprintf because they're MS extensions. -// ----------------------------------------------------------------------------- -#ifdef SS_ANSI - inline int ssvsprintf(PSTR pA, size_t /*nCount*/, PCSTR pFmtA, va_list vl) - { - return vsprintf(pA, pFmtA, vl); - } - inline int ssvsprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) - { - // JMO: It is beginning to seem like Microsoft Visual C++ is the only - // CRT distribution whose version of vswprintf takes THREE arguments. - // All others seem to take FOUR arguments. Therefore instead of - // checking for every possible distro here, I'll assume that unless - // I am running with Microsoft's CRT, then vswprintf takes four - // arguments. If you get a compilation error here, then you can just - // change this code to call the three-argument version. -// #if !defined(__MWERKS__) && !defined(__SUNPRO_CC_COMPAT) && !defined(__SUNPRO_CC) - #ifndef _MSC_VER - return vswprintf(pW, nCount, pFmtW, vl); - #else - nCount; - return vswprintf(pW, pFmtW, vl); - #endif - } -#else - inline int ssnprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl) - { - return _vsnprintf(pA, nCount, pFmtA, vl); - } - inline int ssnprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) - { - return _vsnwprintf(pW, nCount, pFmtW, vl); - } -#endif - - -// ----------------------------------------------------------------------------- -// ssload: Type safe, overloaded ::LoadString wrappers -// There is no equivalent of these in non-Win32-specific builds. However, I'm -// thinking that with the message facet, there might eventually be one -// ----------------------------------------------------------------------------- -#ifdef SS_ANSI -#else - inline int ssload(HMODULE hInst, UINT uId, PSTR pBuf, int nMax) - { - return ::LoadStringA(hInst, uId, pBuf, nMax); - } - inline int ssload(HMODULE hInst, UINT uId, PWSTR pBuf, int nMax) - { - return ::LoadStringW(hInst, uId, pBuf, nMax); - } -#endif - - -// ----------------------------------------------------------------------------- -// sscoll/ssicoll: Collation wrappers -// ----------------------------------------------------------------------------- -#ifdef SS_ANSI - template - inline int sscoll(const CT* sz1, int nLen1, const CT* sz2, int nLen2) - { - const std::collate& coll = - SS_USE_FACET(std::locale(), std::collate); - return coll.compare(sz1, sz1+nLen1, sz2, sz2+nLen2); - } - template - inline int ssicoll(const CT* sz1, int nLen1, const CT* sz2, int nLen2) - { - const std::locale loc; - const std::collate& coll = SS_USE_FACET(loc, std::collate); - - // Some implementations seem to have trouble using the collate<> - // facet typedefs so we'll just default to basic_string and hope - // that's what the collate facet uses (which it generally should) - -// std::collate::string_type s1(sz1); -// std::collate::string_type s2(sz2); - std::basic_string s1(sz1); - std::basic_string s2(sz2); - - sslwr(const_cast(s1.c_str()), nLen1); - sslwr(const_cast(s2.c_str()), nLen2); - return coll.compare(s1.c_str(), s1.c_str()+nLen1, - s2.c_str(), s2.c_str()+nLen2); - } -#else - #ifdef _MBCS - inline int sscoll(PCSTR sz1, int /*nLen1*/, PCSTR sz2, int /*nLen2*/) - { - return _mbscoll((PCUSTR)sz1, (PCUSTR)sz2); - } - inline int ssicoll(PCSTR sz1, int /*nLen1*/, PCSTR sz2, int /*nLen2*/) - { - return _mbsicoll((PCUSTR)sz1, (PCUSTR)sz2); - } - #else - inline int sscoll(PCSTR sz1, int /*nLen1*/, PCSTR sz2, int /*nLen2*/) - { - return strcoll(sz1, sz2); - } - inline int ssicoll(PCSTR sz1, int /*nLen1*/, PCSTR sz2, int /*nLen2*/) - { - return _stricoll(sz1, sz2); - } - #endif - inline int sscoll(PCWSTR sz1, int /*nLen1*/, PCWSTR sz2, int /*nLen2*/) - { - return wcscoll(sz1, sz2); - } - inline int ssicoll(PCWSTR sz1, int /*nLen1*/, PCWSTR sz2, int /*nLen2*/) - { - return _wcsicoll(sz1, sz2); - } -#endif - - -// ----------------------------------------------------------------------------- -// ssfmtmsg: FormatMessage equivalents. Needed because I added a CString facade -// Again -- no equivalent of these on non-Win32 builds but their might one day -// be one if the message facet gets implemented -// ----------------------------------------------------------------------------- -#ifdef SS_ANSI -#else - inline DWORD ssfmtmsg(DWORD dwFlags, LPCVOID pSrc, DWORD dwMsgId, - DWORD dwLangId, PSTR pBuf, DWORD nSize, - va_list* vlArgs) - { - return FormatMessageA(dwFlags, pSrc, dwMsgId, dwLangId, - pBuf, nSize,vlArgs); - } - inline DWORD ssfmtmsg(DWORD dwFlags, LPCVOID pSrc, DWORD dwMsgId, - DWORD dwLangId, PWSTR pBuf, DWORD nSize, - va_list* vlArgs) - { - return FormatMessageW(dwFlags, pSrc, dwMsgId, dwLangId, - pBuf, nSize,vlArgs); - } -#endif - - - -// FUNCTION: sscpy. Copies up to 'nMax' characters from pSrc to pDst. -// ----------------------------------------------------------------------------- -// FUNCTION: sscpy -// inline int sscpy(PSTR pDst, PCSTR pSrc, int nMax=-1); -// inline int sscpy(PUSTR pDst, PCSTR pSrc, int nMax=-1) -// inline int sscpy(PSTR pDst, PCWSTR pSrc, int nMax=-1); -// inline int sscpy(PWSTR pDst, PCWSTR pSrc, int nMax=-1); -// inline int sscpy(PWSTR pDst, PCSTR pSrc, int nMax=-1); -// -// DESCRIPTION: -// This function is very much (but not exactly) like strcpy. These -// overloads simplify copying one C-style string into another by allowing -// the caller to specify two different types of strings if necessary. -// -// The strings must NOT overlap -// -// "Character" is expressed in terms of the destination string, not -// the source. If no 'nMax' argument is supplied, then the number of -// characters copied will be sslen(pSrc). A NULL terminator will -// also be added so pDst must actually be big enough to hold nMax+1 -// characters. The return value is the number of characters copied, -// not including the NULL terminator. -// -// PARAMETERS: -// pSrc - the string to be copied FROM. May be a char based string, an -// MBCS string (in Win32 builds) or a wide string (wchar_t). -// pSrc - the string to be copied TO. Also may be either MBCS or wide -// nMax - the maximum number of characters to be copied into szDest. Note -// that this is expressed in whatever a "character" means to pDst. -// If pDst is a wchar_t type string than this will be the maximum -// number of wchar_ts that my be copied. The pDst string must be -// large enough to hold least nMaxChars+1 characters. -// If the caller supplies no argument for nMax this is a signal to -// the routine to copy all the characters in pSrc, regardless of -// how long it is. -// -// RETURN VALUE: none -// ----------------------------------------------------------------------------- -template -inline int sscpycvt(CT1* pDst, const CT2* pSrc, int nChars) -{ - StdCodeCvt(pDst, pSrc, nChars); - pDst[SSMAX(nChars, 0)] = '\0'; - return nChars; -} - -template -inline int sscpy(CT1* pDst, const CT2* pSrc, int nMax, int nLen) -{ - return sscpycvt(pDst, pSrc, SSMIN(nMax, nLen)); -} -template -inline int sscpy(CT1* pDst, const CT2* pSrc, int nMax) -{ - return sscpycvt(pDst, pSrc, SSMIN(nMax, sslen(pSrc))); -} -template -inline int sscpy(CT1* pDst, const CT2* pSrc) -{ - return sscpycvt(pDst, pSrc, sslen(pSrc)); -} -template -inline int sscpy(CT1* pDst, const std::basic_string& sSrc, int nMax) -{ - return sscpycvt(pDst, sSrc.c_str(), SSMIN(nMax, (int)sSrc.length())); -} -template -inline int sscpy(CT1* pDst, const std::basic_string& sSrc) -{ - return sscpycvt(pDst, sSrc.c_str(), (int)sSrc.length()); -} - -#ifdef SS_INC_COMDEF - template - inline int sscpy(CT1* pDst, const _bstr_t& bs, int nMax) - { - return sscpycvt(pDst, static_cast(bs), SSMIN(nMax, (int)bs.length())); - } - template - inline int sscpy(CT1* pDst, const _bstr_t& bs) - { - return sscpy(pDst, bs, bs.length()); - } -#endif - - -// ----------------------------------------------------------------------------- -// Functional objects for changing case. They also let you pass locales -// ----------------------------------------------------------------------------- - -#ifdef SS_ANSI - template - struct SSToUpper : public std::binary_function - { - inline CT operator()(const CT& t, const std::locale& loc) const - { - return std::toupper(t, loc); - } - }; - template - struct SSToLower : public std::binary_function - { - inline CT operator()(const CT& t, const std::locale& loc) const - { - return std::tolower(t, loc); - } - }; -#endif - -// This struct is used for TrimRight() and TrimLeft() function implementations. -//template -//struct NotSpace : public std::unary_function -//{ -// const std::locale& loc; -// inline NotSpace(const std::locale& locArg) : loc(locArg) {} -// inline bool operator() (CT t) { return !std::isspace(t, loc); } -//}; -template -struct NotSpace : public std::unary_function -{ - const std::locale& loc; - NotSpace(const std::locale& locArg) : loc(locArg) {} - - // DINKUMWARE BUG: - // Note -- using std::isspace in a COM DLL gives us access violations - // because it causes the dynamic addition of a function to be called - // when the library shuts down. Unfortunately the list is maintained - // in DLL memory but the function is in static memory. So the COM DLL - // goes away along with the function that was supposed to be called, - // and then later when the DLL CRT shuts down it unloads the list and - // tries to call the long-gone function. - // This is DinkumWare's implementation problem. Until then, we will - // use good old isspace and iswspace from the CRT unless they - // specify SS_ANSI -#ifdef SS_ANSI - bool operator() (CT t) const { return !std::isspace(t, loc); } -#else - bool ssisp(char c) const { return FALSE != ::isspace((int) c); } - bool ssisp(wchar_t c) const { return FALSE != ::iswspace((wint_t) c); } - bool operator()(CT t) const { return !ssisp(t); } -#endif -}; - - - - -// Now we can define the template (finally!) -// ============================================================================= -// TEMPLATE: CStdStr -// template class CStdStr : public std::basic_string -// -// REMARKS: -// This template derives from basic_string and adds some MFC CString- -// like functionality -// -// Basically, this is my attempt to make Standard C++ library strings as -// easy to use as the MFC CString class. -// -// Note that although this is a template, it makes the assumption that the -// template argument (CT, the character type) is either char or wchar_t. -// ============================================================================= - -//#define CStdStr _SS // avoid compiler warning 4786 - - -template -class CStdStr : public std::basic_string -{ - // Typedefs for shorter names. Using these names also appears to help - // us avoid some ambiguities that otherwise arise on some platforms - - typedef typename std::basic_string MYBASE; // my base class - typedef CStdStr MYTYPE; // myself - typedef typename MYBASE::const_pointer PCMYSTR; // PCSTR or PCWSTR - typedef typename MYBASE::pointer PMYSTR; // PSTR or PWSTR - typedef typename MYBASE::iterator MYITER; // my iterator type - typedef typename MYBASE::const_iterator MYCITER; // you get the idea... - typedef typename MYBASE::reverse_iterator MYRITER; - typedef typename MYBASE::size_type MYSIZE; - typedef typename MYBASE::value_type MYVAL; - typedef typename MYBASE::allocator_type MYALLOC; - -public: - - // shorthand conversion from PCTSTR to string resource ID - #define _TRES(pctstr) (LOWORD((DWORD)(pctstr))) - - // CStdStr inline constructors - CStdStr() - { - } - - CStdStr(const MYTYPE& str) : MYBASE(SSREF(str)) - { - } - - CStdStr(const std::string& str) - { - ssasn(*this, SSREF(str)); - } - - CStdStr(const std::wstring& str) - { - ssasn(*this, SSREF(str)); - } - - CStdStr(PCMYSTR pT, MYSIZE n) : MYBASE(pT, n) - { - } - - CStdStr(PCSTR pA) - { - #ifdef SS_ANSI - *this = pA; - #else - if ( 0 != HIWORD(pA) ) - *this = pA; - else if ( 0 != pA && !Load(_TRES(pA)) ) - TRACE(_T("Can't load string %u\n"), _TRES(pA)); - #endif - } - - CStdStr(PCWSTR pW) - { - #ifdef SS_ANSI - *this = pW; - #else - if ( 0 != HIWORD(pW) ) - *this = pW; - else if ( 0 != pW && !Load(_TRES(pW)) ) - TRACE(_T("Can't load string %u\n"), _TRES(pW)); - #endif - } - - CStdStr(MYCITER first, MYCITER last) - : MYBASE(first, last) - { - } - - CStdStr(MYSIZE nSize, MYVAL ch, const MYALLOC& al=MYALLOC()) - : MYBASE(nSize, ch, al) - { - } - - #ifdef SS_INC_COMDEF - CStdStr(const _bstr_t& bstr) - { - if ( bstr.length() > 0 ) - append(static_cast(bstr), bstr.length()); - } - #endif - - // CStdStr inline assignment operators -- the ssasn function now takes care - // of fixing the MSVC assignment bug (see knowledge base article Q172398). - MYTYPE& operator=(const MYTYPE& str) - { - ssasn(*this, str); - return *this; - } - - MYTYPE& operator=(const std::string& str) - { - ssasn(*this, str); - return *this; - } - - MYTYPE& operator=(const std::wstring& str) - { - ssasn(*this, str); - return *this; - } - - MYTYPE& operator=(PCSTR pA) - { - ssasn(*this, pA); - return *this; - } - - MYTYPE& operator=(PCWSTR pW) - { - ssasn(*this, pW); - return *this; - } - - MYTYPE& operator=(CT t) - { - Q172398(*this); - MYBASE::assign(1, t); - return *this; - } - - #ifdef SS_INC_COMDEF - MYTYPE& operator=(const _bstr_t& bstr) - { - if ( bstr.length() > 0 ) - return assign(static_cast(bstr), bstr.length()); - else - { - erase(); - return *this; - } - } - #endif - - - // Overloads also needed to fix the MSVC assignment bug (KB: Q172398) - // *** Thanks to Pete The Plumber for catching this one *** - // They also are compiled if you have explicitly turned off refcounting - #if ( defined(_MSC_VER) && ( _MSC_VER < 1200 ) ) || defined(SS_NO_REFCOUNT) - - MYTYPE& assign(const MYTYPE& str) - { - ssasn(*this, str); - return *this; - } - - MYTYPE& assign(const MYTYPE& str, MYSIZE nStart, MYSIZE nChars) - { - // This overload of basic_string::assign is supposed to assign up to - // or the NULL terminator, whichever comes first. Since we - // are about to call a less forgiving overload (in which - // must be a valid length), we must adjust the length here to a safe - // value. Thanks to Ullrich Pollähne for catching this bug - - nChars = SSMIN(nChars, str.length() - nStart); - - // Watch out for assignment to self - - if ( this == &str ) - { - MYTYPE strTemp(str.c_str()+nStart, nChars); - assign(strTemp); - } - else - { - Q172398(*this); - MYBASE::assign(str.c_str()+nStart, nChars); - } - return *this; - } - - MYTYPE& assign(const MYBASE& str) - { - ssasn(*this, str); - return *this; - } - - MYTYPE& assign(const MYBASE& str, MYSIZE nStart, MYSIZE nChars) - { - // This overload of basic_string::assign is supposed to assign up to - // or the NULL terminator, whichever comes first. Since we - // are about to call a less forgiving overload (in which - // must be a valid length), we must adjust the length here to a safe - // value. Thanks to Ullrich Pollähne for catching this bug - - nChars = SSMIN(nChars, str.length() - nStart); - - // Watch out for assignment to self - - if ( this == &str ) // watch out for assignment to self - { - MYTYPE strTemp(str.c_str() + nStart, nChars); - assign(strTemp); - } - else - { - Q172398(*this); - MYBASE::assign(str.c_str()+nStart, nChars); - } - return *this; - } - - MYTYPE& assign(const CT* pC, MYSIZE nChars) - { - // Q172398 only fix -- erase before assigning, but not if we're - // assigning from our own buffer - - #if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) - if ( !empty() && ( pC < data() || pC > data() + capacity() ) ) - erase(); - #endif - Q172398(*this); - MYBASE::assign(pC, nChars); - return *this; - } - - MYTYPE& assign(MYSIZE nChars, MYVAL val) - { - Q172398(*this); - MYBASE::assign(nChars, val); - return *this; - } - - MYTYPE& assign(const CT* pT) - { - return assign(pT, CStdStr::traits_type::length(pT)); - } - - MYTYPE& assign(MYCITER iterFirst, MYCITER iterLast) - { - #if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) - // Q172398 fix. don't call erase() if we're assigning from ourself - if ( iterFirst < begin() || iterFirst > begin() + size() ) - erase() - #endif - replace(begin(), end(), iterFirst, iterLast); - return *this; - } - #endif - - - // ------------------------------------------------------------------------- - // CStdStr inline concatenation. - // ------------------------------------------------------------------------- - MYTYPE& operator+=(const MYTYPE& str) - { - ssadd(*this, str); - return *this; - } - - MYTYPE& operator+=(const std::string& str) - { - ssadd(*this, str); - return *this; - } - - MYTYPE& operator+=(const std::wstring& str) - { - ssadd(*this, str); - return *this; - } - - MYTYPE& operator+=(PCSTR pA) - { - ssadd(*this, pA); - return *this; - } - - MYTYPE& operator+=(PCWSTR pW) - { - ssadd(*this, pW); - return *this; - } - - MYTYPE& operator+=(CT t) - { - append(1, t); - return *this; - } - #ifdef SS_INC_COMDEF // if we have _bstr_t, define a += for it too. - MYTYPE& operator+=(const _bstr_t& bstr) - { - return operator+=(static_cast(bstr)); - } - #endif - - - // addition operators -- global friend functions. - - friend MYTYPE operator+(const MYTYPE& str1, const MYTYPE& str2); - friend MYTYPE operator+(const MYTYPE& str, CT t); - friend MYTYPE operator+(const MYTYPE& str, PCSTR sz); - friend MYTYPE operator+(const MYTYPE& str, PCWSTR sz); - friend MYTYPE operator+(PCSTR pA, const MYTYPE& str); - friend MYTYPE operator+(PCWSTR pW, const MYTYPE& str); -#ifdef SS_INC_COMDEF - friend MYTYPE operator+(const _bstr_t& bstr, const MYTYPE& str); - friend MYTYPE operator+(const MYTYPE& str, const _bstr_t& bstr); -#endif - - // ------------------------------------------------------------------------- - // Case changing functions - // ------------------------------------------------------------------------- - // ------------------------------------------------------------------------- - MYTYPE& ToUpper() - { - // Strictly speaking, this would be about the most portable way - - // std::transform(begin(), - // end(), - // begin(), - // std::bind2nd(SSToUpper(), std::locale())); - - // But practically speaking, this works faster - - if ( !empty() ) - ssupr(GetBuf(), size()); - - return *this; - } - - - - MYTYPE& ToLower() - { - // Strictly speaking, this would be about the most portable way - - // std::transform(begin(), - // end(), - // begin(), - // std::bind2nd(SSToLower(), std::locale())); - - // But practically speaking, this works faster - - if ( !empty() ) - sslwr(GetBuf(), size()); - - return *this; - } - - - - MYTYPE& Normalize() - { - return Trim().ToLower(); - } - - - // ------------------------------------------------------------------------- - // CStdStr -- Direct access to character buffer. In the MS' implementation, - // the at() function that we use here also calls _Freeze() providing us some - // protection from multithreading problems associated with ref-counting. - // ------------------------------------------------------------------------- - CT* GetBuf(int nMinLen=-1) - { - if ( static_cast(size()) < nMinLen ) - resize(static_cast(nMinLen)); - - return empty() ? const_cast(data()) : &(at(0)); - } - - CT* SetBuf(int nLen) - { - nLen = ( nLen > 0 ? nLen : 0 ); - if ( capacity() < 1 && nLen == 0 ) - resize(1); - - resize(static_cast(nLen)); - return const_cast(data()); - } - void RelBuf(int nNewLen=-1) - { - resize(static_cast(nNewLen > -1 ? nNewLen : sslen(c_str()))); - } - - void BufferRel() { RelBuf(); } // backwards compatability - CT* Buffer() { return GetBuf(); } // backwards compatability - CT* BufferSet(int nLen) { return SetBuf(nLen);}// backwards compatability - - bool Equals(const CT* pT, bool bUseCase=false) const - { // get copy, THEN compare (thread safe) - return bUseCase ? compare(pT) == 0 : ssicmp(MYTYPE(*this), pT) == 0; - } - - // ------------------------------------------------------------------------- - // FUNCTION: CStdStr::Load - // REMARKS: - // Loads string from resource specified by nID - // - // PARAMETERS: - // nID - resource Identifier. Purely a Win32 thing in this case - // - // RETURN VALUE: - // true if successful, false otherwise - // ------------------------------------------------------------------------- -#ifndef SS_ANSI - bool Load(UINT nId, HMODULE hModule=NULL) - { - bool bLoaded = false; // set to true of we succeed. - - #ifdef _MFC_VER // When in Rome... - - CString strRes; - bLoaded = FALSE != strRes.LoadString(nId); - if ( bLoaded ) - *this = strRes; - - #else - - // Get the resource name and module handle - - if ( NULL == hModule ) - hModule = GetResourceHandle(); - - PCTSTR szName = MAKEINTRESOURCE((nId>>4)+1); // lifted - DWORD dwSize = 0; - - // No sense continuing if we can't find the resource - - HRSRC hrsrc = ::FindResource(hModule, szName, RT_STRING); - - if ( NULL == hrsrc ) - TRACE(_T("Cannot find resource %d: 0x%X"), nId, ::GetLastError()); - else if ( 0 == (dwSize = ::SizeofResource(hModule, hrsrc) / sizeof(CT))) - TRACE(_T("Cant get size of resource %d 0x%X\n"),nId,GetLastError()); - else - { - bLoaded = 0 != ssload(hModule, nId, GetBuf(dwSize), dwSize); - ReleaseBuffer(); - } - - #endif - - if ( !bLoaded ) - TRACE(_T("String not loaded 0x%X\n"), ::GetLastError()); - - return bLoaded; - } -#endif - - // ------------------------------------------------------------------------- - // FUNCTION: CStdStr::Format - // void _cdecl Formst(CStdStringA& PCSTR szFormat, ...) - // void _cdecl Format(PCSTR szFormat); - // - // DESCRIPTION: - // This function does sprintf/wsprintf style formatting on CStdStringA - // objects. It looks a lot like MFC's CString::Format. Some people - // might even call this identical. Fortunately, these people are now - // dead. - // - // PARAMETERS: - // nId - ID of string resource holding the format string - // szFormat - a PCSTR holding the format specifiers - // argList - a va_list holding the arguments for the format specifiers. - // - // RETURN VALUE: None. - // ------------------------------------------------------------------------- - // formatting (using wsprintf style formatting) - #ifndef SS_ANSI - void Format(UINT nId, ...) - { - va_list argList; - va_start(argList, nId); - va_start(argList, nId); - - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - FormatV(strFmt, argList); - - va_end(argList); - } - #endif - void Format(const CT* szFmt, ...) - { - va_list argList; - va_start(argList, szFmt); - FormatV(szFmt, argList); - va_end(argList); - } - void AppendFormat(const CT* szFmt, ...) - { - va_list argList; - va_start(argList, szFmt); - AppendFormatV(szFmt, argList); - va_end(argList); - } - - #define MAX_FMT_TRIES 5 // #of times we try - #define FMT_BLOCK_SIZE 2048 // # of bytes to increment per try - #define BUFSIZE_1ST 256 - #define BUFSIZE_2ND 512 - #define STD_BUF_SIZE 1024 - - // an efficient way to add formatted characters to the string. You may only - // add up to STD_BUF_SIZE characters at a time, though - void AppendFormatV(const CT* szFmt, va_list argList) - { - CT szBuf[STD_BUF_SIZE]; - #ifdef SS_ANSI - int nLen = ssvsprintf(szBuf, STD_BUF_SIZE-1, szFmt, argList); - #else - int nLen = ssnprintf(szBuf, STD_BUF_SIZE-1, szFmt, argList); - #endif - if ( 0 < nLen ) - append(szBuf, nLen); - } - - // ------------------------------------------------------------------------- - // FUNCTION: FormatV - // void FormatV(PCSTR szFormat, va_list, argList); - // - // DESCRIPTION: - // This function formats the string with sprintf style format-specs. - // It makes a general guess at required buffer size and then tries - // successively larger buffers until it finds one big enough or a - // threshold (MAX_FMT_TRIES) is exceeded. - // - // PARAMETERS: - // szFormat - a PCSTR holding the format of the output - // argList - a Microsoft specific va_list for variable argument lists - // - // RETURN VALUE: - // ------------------------------------------------------------------------- - - void FormatV(const CT* szFormat, va_list argList) - { - #ifdef SS_ANSI - - int nLen = sslen(szFormat) + STD_BUF_SIZE; - ssvsprintf(GetBuffer(nLen), nLen-1, szFormat, argList); - ReleaseBuffer(); - - #else - - CT* pBuf = NULL; - int nChars = 1; - int nUsed = 0; - size_type nActual = 0; - int nTry = 0; - - do - { - // Grow more than linearly (e.g. 512, 1536, 3072, etc) - - nChars += ((nTry+1) * FMT_BLOCK_SIZE); - pBuf = reinterpret_cast(_alloca(sizeof(CT)*nChars)); - nUsed = ssnprintf(pBuf, nChars-1, szFormat, argList); - - // Ensure proper NULL termination. - - nActual = nUsed == -1 ? nChars-1 : SSMIN(nUsed, nChars-1); - pBuf[nActual+1]= '\0'; - - - } while ( nUsed < 0 && nTry++ < MAX_FMT_TRIES ); - - // assign whatever we managed to format - - assign(pBuf, nActual); - - #endif - } - - - // ------------------------------------------------------------------------- - // CString Facade Functions: - // - // The following methods are intended to allow you to use this class as a - // drop-in replacement for CString. - // ------------------------------------------------------------------------- - #ifndef SS_ANSI - BSTR AllocSysString() const - { - ostring os; - ssasn(os, *this); - return ::SysAllocString(os.c_str()); - } - #endif - - int Collate(PCMYSTR szThat) const - { - return sscoll(c_str(), length(), szThat, sslen(szThat)); - } - - int CollateNoCase(PCMYSTR szThat) const - { - return ssicoll(c_str(), length(), szThat, sslen(szThat)); - } - - int Compare(PCMYSTR szThat) const - { - return MYBASE::compare(szThat); - } - - int CompareNoCase(PCMYSTR szThat) const - { - return ssicmp(c_str(), szThat); - } - - int Delete(int nIdx, int nCount=1) - { - if ( nIdx < GetLength() ) - erase(static_cast(nIdx), static_cast(nCount)); - - return GetLength(); - } - - void Empty() - { - erase(); - } - - int Find(CT ch) const - { - MYSIZE nIdx = find_first_of(ch); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - int Find(PCMYSTR szSub) const - { - MYSIZE nIdx = find(szSub); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - int Find(CT ch, int nStart) const - { - // CString::Find docs say add 1 to nStart when it's not zero - // CString::Find code doesn't do that however. We'll stick - // with what the code does - - MYSIZE nIdx = find_first_of(ch, static_cast(nStart)); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - int Find(PCMYSTR szSub, int nStart) const - { - // CString::Find docs say add 1 to nStart when it's not zero - // CString::Find code doesn't do that however. We'll stick - // with what the code does - - MYSIZE nIdx = find(szSub, static_cast(nStart)); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - int FindOneOf(PCMYSTR szCharSet) const - { - MYSIZE nIdx = find_first_of(szCharSet); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - -#ifndef SS_ANSI - void FormatMessage(PCMYSTR szFormat, ...) throw(std::exception) - { - va_list argList; - va_start(argList, szFormat); - PMYSTR szTemp; - if ( ssfmtmsg(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, - szFormat, 0, 0, - reinterpret_cast(&szTemp), 0, &argList) == 0 || - szTemp == 0 ) - { - throw std::runtime_error("out of memory"); - } - *this = szTemp; - LocalFree(szTemp); - va_end(argList); - } - - void FormatMessage(UINT nFormatId, ...) throw(std::exception) - { - MYTYPE sFormat; - VERIFY(sFormat.LoadString(nFormatId) != 0); - va_list argList; - va_start(argList, nFormatId); - PMYSTR szTemp; - if ( ssfmtmsg(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, - sFormat, 0, 0, - reinterpret_cast(&szTemp), 0, &argList) == 0 || - szTemp == 0) - { - throw std::runtime_error("out of memory"); - } - *this = szTemp; - LocalFree(szTemp); - va_end(argList); - } -#endif - - - // ------------------------------------------------------------------------- - // GetXXXX -- Direct access to character buffer - // ------------------------------------------------------------------------- - CT GetAt(int nIdx) const - { - return at(static_cast(nIdx)); - } - - CT* GetBuffer(int nMinLen=-1) - { - return GetBuf(nMinLen); - } - - CT* GetBufferSetLength(int nLen) - { - return BufferSet(nLen); - } - - // GetLength() -- MFC docs say this is the # of BYTES but - // in truth it is the number of CHARACTERs (chars or wchar_ts) - int GetLength() const - { - return static_cast(length()); - } - - - int Insert(int nIdx, CT ch) - { - if ( static_cast(nIdx) > size() -1 ) - append(1, ch); - else - insert(static_cast(nIdx), 1, ch); - - return GetLength(); - } - int Insert(int nIdx, PCMYSTR sz) - { - if ( nIdx >= size() ) - append(sz, sslen(sz)); - else - insert(static_cast(nIdx), sz); - - return GetLength(); - } - - bool IsEmpty() const - { - return empty(); - } - - MYTYPE Left(int nCount) const - { - return substr(0, static_cast(nCount)); - } - - #ifndef SS_ANSI - bool LoadString(UINT nId) - { - return this->Load(nId); - } - #endif - - void MakeLower() - { - ToLower(); - } - - void MakeReverse() - { - std::reverse(begin(), end()); - } - - void MakeUpper() - { - ToUpper(); - } - - MYTYPE Mid(int nFirst ) const - { - return substr(static_cast(nFirst)); - } - - MYTYPE Mid(int nFirst, int nCount) const - { - return substr(static_cast(nFirst), static_cast(nCount)); - } - - void ReleaseBuffer(int nNewLen=-1) - { - RelBuf(nNewLen); - } - - int Remove(CT ch) - { - MYSIZE nIdx = 0; - int nRemoved = 0; - while ( (nIdx=find_first_of(ch)) != MYBASE::npos ) - { - erase(nIdx, 1); - nRemoved++; - } - return nRemoved; - } - - int Replace(CT chOld, CT chNew) - { - int nReplaced = 0; - for ( MYITER iter=begin(); iter != end(); iter++ ) - { - if ( *iter == chOld ) - { - *iter = chNew; - nReplaced++; - } - } - return nReplaced; - } - - int Replace(PCMYSTR szOld, PCMYSTR szNew) - { - int nReplaced = 0; - MYSIZE nIdx = 0; - MYSIZE nOldLen = sslen(szOld); - if ( 0 == nOldLen ) - return 0; - - static const CT ch = CT(0); - MYSIZE nNewLen = sslen(szNew); - PCMYSTR szRealNew = szNew == 0 ? &ch : szNew; - - while ( (nIdx=find(szOld, nIdx)) != MYBASE::npos ) - { - replace(begin()+nIdx, begin()+nIdx+nOldLen, szRealNew); - nReplaced++; - nIdx += nNewLen; - } - return nReplaced; - } - - int ReverseFind(CT ch) const - { - MYSIZE nIdx = find_last_of(ch); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - // ReverseFind overload that's not in CString but might be useful - int ReverseFind(PCMYSTR szFind, MYSIZE pos=MYBASE::npos) const - { - MYSIZE nIdx = rfind(0 == szFind ? MYTYPE() : szFind, pos); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - MYTYPE Right(int nCount) const - { - nCount = SSMIN(nCount, static_cast(size())); - return substr(size()-static_cast(nCount)); - } - - void SetAt(int nIndex, CT ch) - { - ASSERT(size() > static_cast(nIndex)); - at(static_cast(nIndex)) = ch; - } - - #ifndef SS_ANSI - BSTR SetSysString(BSTR* pbstr) const - { - ostring os; - ssasn(os, *this); - if ( !::SysReAllocStringLen(pbstr, os.c_str(), os.length()) ) - throw std::runtime_error("out of memory"); - - ASSERT(*pbstr != 0); - return *pbstr; - } - #endif - - MYTYPE SpanExcluding(PCMYSTR szCharSet) const - { - return Left(find_first_of(szCharSet)); - } - - MYTYPE SpanIncluding(PCMYSTR szCharSet) const - { - return Left(find_first_not_of(szCharSet)); - } - - #if !defined(UNICODE) && !defined(SS_ANSI) - - // CString's OemToAnsi and AnsiToOem functions are available only in - // Unicode builds. However since we're a template we also need a - // runtime check of CT and a reinterpret_cast to account for the fact - // that CStdStringW gets instantiated even in non-Unicode builds. - - void AnsiToOem() - { - if ( sizeof(CT) == sizeof(char) && !empty() ) - { - ::CharToOem(reinterpret_cast(c_str()), - reinterpret_cast(GetBuf())); - } - else - { - ASSERT(false); - } - } - - void OemToAnsi() - { - if ( sizeof(CT) == sizeof(char) && !empty() ) - { - ::OemToChar(reinterpret_cast(c_str()), - reinterpret_cast(GetBuf())); - } - else - { - ASSERT(false); - } - } - - #endif - - - // ------------------------------------------------------------------------- - // Trim and its variants - // ------------------------------------------------------------------------- - MYTYPE& Trim() - { - return TrimLeft().TrimRight(); - } - - MYTYPE& TrimLeft() - { - erase(begin(), std::find_if(begin(),end(),NotSpace(std::locale()))); - return *this; - } - - MYTYPE& TrimLeft(CT tTrim) - { - erase(0, find_first_not_of(tTrim)); - return *this; - } - - MYTYPE& TrimLeft(PCMYSTR szTrimChars) - { - erase(0, find_first_not_of(szTrimChars)); - return *this; - } - - MYTYPE& TrimRight() - { - std::locale loc; - MYRITER it = std::find_if(rbegin(), rend(), NotSpace(loc)); - if ( rend() != it ) - erase(rend() - it); - - erase(it != rend() ? find_last_of(*it) + 1 : 0); - return *this; - } - - MYTYPE& TrimRight(CT tTrim) - { - MYSIZE nIdx = find_last_not_of(tTrim); - erase(MYBASE::npos == nIdx ? 0 : ++nIdx); - return *this; - } - - MYTYPE& TrimRight(PCMYSTR szTrimChars) - { - MYSIZE nIdx = find_last_not_of(szTrimChars); - erase(MYBASE::npos == nIdx ? 0 : ++nIdx); - return *this; - } - - void FreeExtra() - { - MYTYPE mt; - swap(mt); - if ( !mt.empty() ) - assign(mt.c_str(), mt.size()); - } - - // I have intentionally not implemented the following CString - // functions. You cannot make them work without taking advantage - // of implementation specific behavior. However if you absolutely - // MUST have them, uncomment out these lines for "sort-of-like" - // their behavior. You're on your own. - -// CT* LockBuffer() { return GetBuf(); }// won't really lock -// void UnlockBuffer(); { } // why have UnlockBuffer w/o LockBuffer? - - // Array-indexing operators. Required because we defined an implicit cast - // to operator const CT* (Thanks to Julian Selman for pointing this out) - CT& operator[](int nIdx) - { - return MYBASE::operator[](static_cast(nIdx)); - } - - const CT& operator[](int nIdx) const - { - return MYBASE::operator[](static_cast(nIdx)); - } - - CT& operator[](unsigned int nIdx) - { - return MYBASE::operator[](static_cast(nIdx)); - } - - const CT& operator[](unsigned int nIdx) const - { - return MYBASE::operator[](static_cast(nIdx)); - } - - operator const CT*() const - { - return c_str(); - } - - // IStream related functions. Useful in IPersistStream implementations - -#ifdef SS_INC_COMDEF - - // struct SSSHDR - useful for non Std C++ persistence schemes. - typedef struct SSSHDR - { - BYTE byCtrl; - ULONG nChars; - } SSSHDR; // as in "Standard String Stream Header" - - #define SSSO_UNICODE 0x01 // the string is a wide string - #define SSSO_COMPRESS 0x02 // the string is compressed - - // ------------------------------------------------------------------------- - // FUNCTION: StreamSize - // REMARKS: - // Returns how many bytes it will take to StreamSave() this CStdString - // object to an IStream. - // ------------------------------------------------------------------------- - ULONG StreamSize() const - { - // Control header plus string - ASSERT(size()*sizeof(CT) < 0xffffffffUL - sizeof(SSSHDR)); - return (size() * sizeof(CT)) + sizeof(SSSHDR); - } - - // ------------------------------------------------------------------------- - // FUNCTION: StreamSave - // REMARKS: - // Saves this CStdString object to a COM IStream. - // ------------------------------------------------------------------------- - HRESULT StreamSave(IStream* pStream) const - { - ASSERT(size()*sizeof(CT) < 0xffffffffUL - sizeof(SSSHDR)); - HRESULT hr = E_FAIL; - ASSERT(pStream != 0); - SSSHDR hdr; - hdr.byCtrl = sizeof(CT) == 2 ? SSSO_UNICODE : 0; - hdr.nChars = size(); - - - if ( FAILED(hr=pStream->Write(&hdr, sizeof(SSSHDR), 0)) ) - TRACE(_T("StreamSave: Cannot write control header, ERR=0x%X\n"),hr); - else if ( empty() ) - ; // nothing to write - else if ( FAILED(hr=pStream->Write(c_str(), size()*sizeof(CT), 0)) ) - TRACE(_T("StreamSave: Cannot write string to stream 0x%X\n"), hr); - - return hr; - } - - - // ------------------------------------------------------------------------- - // FUNCTION: StreamLoad - // REMARKS: - // This method loads the object from an IStream. - // ------------------------------------------------------------------------- - HRESULT StreamLoad(IStream* pStream) - { - ASSERT(pStream != 0); - SSSHDR hdr; - HRESULT hr = E_FAIL; - - if ( FAILED(hr=pStream->Read(&hdr, sizeof(SSSHDR), 0)) ) - { - TRACE(_T("StreamLoad: Cant read control header, ERR=0x%X\n"), hr); - } - else if ( hdr.nChars > 0 ) - { - ULONG nRead = 0; - PMYSTR pMyBuf = BufferSet(hdr.nChars); - - // If our character size matches the character size of the string - // we're trying to read, then we can read it directly into our - // buffer. Otherwise, we have to read into an intermediate buffer - // and convert. - - if ( (hdr.byCtrl & SSSO_UNICODE) != 0 ) - { - ULONG nBytes = hdr.nChars * sizeof(wchar_t); - if ( sizeof(CT) == sizeof(wchar_t) ) - { - if ( FAILED(hr=pStream->Read(pMyBuf, nBytes, &nRead)) ) - TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), hr); - } - else - { - PWSTR pBufW = reinterpret_cast(_alloca((nBytes)+1)); - if ( FAILED(hr=pStream->Read(pBufW, nBytes, &nRead)) ) - TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), hr); - else - sscpy(pMyBuf, pBufW, hdr.nChars); - } - } - else - { - ULONG nBytes = hdr.nChars * sizeof(char); - if ( sizeof(CT) == sizeof(char) ) - { - if ( FAILED(hr=pStream->Read(pMyBuf, nBytes, &nRead)) ) - TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), hr); - } - else - { - PSTR pBufA = reinterpret_cast(_alloca(nBytes)); - if ( FAILED(hr=pStream->Read(pBufA, hdr.nChars, &nRead)) ) - TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), hr); - else - sscpy(pMyBuf, pBufA, hdr.nChars); - } - } - } - else - { - this->erase(); - } - return hr; - } -#endif // #ifdef SS_INC_COMDEF - -#ifndef SS_ANSI - - // SetResourceHandle/GetResourceHandle. In MFC builds, these map directly - // to AfxSetResourceHandle and AfxGetResourceHandle. In non-MFC builds they - // point to a single static HINST so that those who call the member - // functions that take resource IDs can provide an alternate HINST of a DLL - // to search. This is not exactly the list of HMODULES that MFC provides - // but it's better than nothing. - - #ifdef _MFC_VER - static void SetResourceHandle(HMODULE hNew) - { - AfxSetResourceHandle(hNew); - } - static HMODULE GetResourceHandle() - { - return AfxGetResourceHandle(); - } - #else - static void SetResourceHandle(HMODULE hNew) - { - SSResourceHandle() = hNew; - } - static HMODULE GetResourceHandle() - { - return SSResourceHandle(); - } - #endif - -#endif -}; - - - -// ----------------------------------------------------------------------------- -// CStdStr friend addition functions defined as inline -// ----------------------------------------------------------------------------- -template -inline -CStdStr operator+(const CStdStr& str1, const CStdStr& str2) -{ - CStdStr strRet(SSREF(str1)); - strRet.append(str2); - return strRet; -} - -template -inline -CStdStr operator+(const CStdStr& str, CT t) -{ - // this particular overload is needed for disabling reference counting - // though it's only an issue from line 1 to line 2 - - CStdStr strRet(SSREF(str)); // 1 - strRet.append(1, t); // 2 - return strRet; -} - -template -inline -CStdStr operator+(const CStdStr& str, PCSTR pA) -{ - return CStdStr(str) + CStdStr(pA); -} - -template -inline -CStdStr operator+(PCSTR pA, const CStdStr& str) -{ - CStdStr strRet(pA); - strRet.append(str); - return strRet; -} - -template -inline -CStdStr operator+(const CStdStr& str, PCWSTR pW) -{ - return CStdStr(SSREF(str)) + CStdStr(pW); -} - -template -inline -CStdStr operator+(PCWSTR pW, const CStdStr& str) -{ - CStdStr strRet(pW); - strRet.append(str); - return strRet; -} - -#ifdef SS_INC_COMDEF - template - inline - CStdStr operator+(const _bstr_t& bstr, const CStdStr& str) - { - return static_cast(bstr) + str; - } - - template - inline - CStdStr operator+(const CStdStr& str, const _bstr_t& bstr) - { - return str + static_cast(bstr); - } -#endif - - - - -// ----------------------------------------------------------------------------- -// These versions of operator+ provided by Scott Hathaway in order to allow -// CStdString to build on Sun Unix systems. -// ----------------------------------------------------------------------------- - -#if defined(__SUNPRO_CC_COMPAT) || defined(__SUNPRO_CC) - -// Made non-template versions due to "undefined" errors on Sun Forte compiler -// when linking with friend template functions -inline -CStdStr operator+(const CStdStr& str1, - const CStdStr& str2) -{ - CStdStr strRet(SSREF(str1)); - strRet.append(str2); - return strRet; -} - -inline -CStdStr operator+(const CStdStr& str, wchar_t t) -{ - // this particular overload is needed for disabling reference counting - // though it's only an issue from line 1 to line 2 - - CStdStr strRet(SSREF(str)); // 1 - strRet.append(1, t); // 2 - return strRet; -} - -inline -CStdStr operator+(const CStdStr& str, PCWSTR pW) -{ - return CStdStr(str) + CStdStr(pW); -} - -inline -CStdStr operator+(PCWSTR pA, const CStdStr& str) -{ - CStdStr strRet(pA); - strRet.append(str); - return strRet; -} - -inline -CStdStr operator+(const CStdStr& str, PCSTR pW) -{ - return CStdStr(SSREF(str)) + CStdStr(pW); -} - -inline -CStdStr operator+(PCSTR pW, const CStdStr& str) -{ - CStdStr strRet(pW); - strRet.append(str); - return strRet; -} - -inline -CStdStr operator+(const CStdStr& str1, const CStdStr& str2) -{ - CStdStr strRet(SSREF(str1)); - strRet.append(str2); - return strRet; -} - -inline -CStdStr operator+(const CStdStr& str, char t) -{ - // this particular overload is needed for disabling reference counting - // though it's only an issue from line 1 to line 2 - - CStdStr strRet(SSREF(str)); // 1 - strRet.append(1, t); // 2 - return strRet; -} - -inline -CStdStr operator+(const CStdStr& str, PCSTR pA) -{ - return CStdStr(str) + CStdStr(pA); -} - -inline -CStdStr operator+(PCSTR pA, const CStdStr& str) -{ - CStdStr strRet(pA); - strRet.append(str); - return strRet; -} - -inline -CStdStr operator+(const CStdStr& str, PCWSTR pW) -{ - return CStdStr(SSREF(str)) + CStdStr(pW); -} - -inline -CStdStr operator+(PCWSTR pW, const CStdStr& str) -{ - CStdStr strRet(pW); - strRet.append(str); - return strRet; -} - - -#endif // defined(__SUNPRO_CC_COMPAT) || defined(__SUNPRO_CC) - - -// ============================================================================= -// END OF CStdStr INLINE FUNCTION DEFINITIONS -// ============================================================================= - -// Now typedef our class names based upon this humongous template - -typedef CStdStr CStdStringA; // a better std::string -typedef CStdStr CStdStringW; // a better std::wstring -typedef CStdStr CStdStringO; // almost always CStdStringW - -#ifndef SS_ANSI - // SSResourceHandle: our MFC-like resource handle - inline HMODULE& SSResourceHandle() - { - static HMODULE hModuleSS = GetModuleHandle(0); - return hModuleSS; - } -#endif - - -// In MFC builds, define some global serialization operators -// Special operators that allow us to serialize CStdStrings to CArchives. -// Note that we use an intermediate CString object in order to ensure that -// we use the exact same format. - -#ifdef _MFC_VER - inline CArchive& AFXAPI operator<<(CArchive& ar, const CStdStringA& strA) - { - CString strTemp = strA; - return ar << strTemp; - } - inline CArchive& AFXAPI operator<<(CArchive& ar, const CStdStringW& strW) - { - CString strTemp = strW; - return ar << strTemp; - } - - inline CArchive& AFXAPI operator>>(CArchive& ar, CStdStringA& strA) - { - CString strTemp; - ar >> strTemp; - strA = strTemp; - return ar; - } - inline CArchive& AFXAPI operator>>(CArchive& ar, CStdStringW& strW) - { - CString strTemp; - ar >> strTemp; - strW = strTemp; - return ar; - } -#endif // #ifdef _MFC_VER -- (i.e. is this MFC?) - - - -// ----------------------------------------------------------------------------- -// HOW TO EXPORT CSTDSTRING FROM A DLL -// -// If you want to export CStdStringA and CStdStringW from a DLL, then all you -// need to -// 1. make sure that all components link to the same DLL version -// of the CRT (not the static one). -// 2. Uncomment the 3 lines of code below -// 3. #define 2 macros per the instructions in MS KnowledgeBase -// article Q168958. The macros are: -// -// MACRO DEFINTION WHEN EXPORTING DEFINITION WHEN IMPORTING -// ----- ------------------------ ------------------------- -// SSDLLEXP (nothing, just #define it) extern -// SSDLLSPEC __declspec(dllexport) __declspec(dllimport) -// -// Note that these macros must be available to ALL clients who want to -// link to the DLL and use the class. If they -// ----------------------------------------------------------------------------- -//#pragma warning(disable:4231) // non-standard extension ("extern template") -// SSDLLEXP template class SSDLLSPEC CStdStr; -// SSDLLEXP template class SSDLLSPEC CStdStr; - - -// ----------------------------------------------------------------------------- -// GLOBAL FUNCTION: WUFormat -// CStdStringA WUFormat(UINT nId, ...); -// CStdStringA WUFormat(PCSTR szFormat, ...); -// -// REMARKS: -// This function allows the caller for format and return a CStdStringA -// object with a single line of code. -// ----------------------------------------------------------------------------- -#ifdef SS_ANSI -#else - inline CStdStringA WUFormatA(UINT nId, ...) - { - va_list argList; - va_start(argList, nId); - - CStdStringA strFmt; - CStdStringA strOut; - if ( strFmt.Load(nId) ) - strOut.FormatV(strFmt, argList); - - va_end(argList); - return strOut; - } - inline CStdStringA WUFormatA(PCSTR szFormat, ...) - { - va_list argList; - va_start(argList, szFormat); - CStdStringA strOut; - strOut.FormatV(szFormat, argList); - va_end(argList); - return strOut; - } - - inline CStdStringW WUFormatW(UINT nId, ...) - { - va_list argList; - va_start(argList, nId); - - CStdStringW strFmt; - CStdStringW strOut; - if ( strFmt.Load(nId) ) - strOut.FormatV(strFmt, argList); - - va_end(argList); - return strOut; - } - inline CStdStringW WUFormatW(PCWSTR szwFormat, ...) - { - va_list argList; - va_start(argList, szwFormat); - CStdStringW strOut; - strOut.FormatV(szwFormat, argList); - va_end(argList); - return strOut; - } -#endif // #ifdef SS_ANSI - -#ifdef SS_ANSI -#else - // ------------------------------------------------------------------------- - // FUNCTION: WUSysMessage - // CStdStringA WUSysMessageA(DWORD dwError, DWORD dwLangId=SS_DEFLANGID); - // CStdStringW WUSysMessageW(DWORD dwError, DWORD dwLangId=SS_DEFLANGID); - // - // DESCRIPTION: - // This function simplifies the process of obtaining a string equivalent - // of a system error code returned from GetLastError(). You simply - // supply the value returned by GetLastError() to this function and the - // corresponding system string is returned in the form of a CStdStringA. - // - // PARAMETERS: - // dwError - a DWORD value representing the error code to be translated - // dwLangId - the language id to use. defaults to english. - // - // RETURN VALUE: - // a CStdStringA equivalent of the error code. Currently, this function - // only returns either English of the system default language strings. - // ------------------------------------------------------------------------- - #define SS_DEFLANGID MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT) - inline CStdStringA WUSysMessageA(DWORD dwError, DWORD dwLangId=SS_DEFLANGID) - { - CHAR szBuf[512]; - - if ( 0 != ::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, - dwLangId, szBuf, 511, NULL) ) - return WUFormatA("%s (0x%X)", szBuf, dwError); - else - return WUFormatA("Unknown error (0x%X)", dwError); - } - inline CStdStringW WUSysMessageW(DWORD dwError, DWORD dwLangId=SS_DEFLANGID) - { - WCHAR szBuf[512]; - - if ( 0 != ::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, - dwLangId, szBuf, 511, NULL) ) - return WUFormatW(L"%s (0x%X)", szBuf, dwError); - else - return WUFormatW(L"Unknown error (0x%X)", dwError); - } -#endif - -// Define TCHAR based friendly names for some of these functions - -#ifdef UNICODE - #define CStdString CStdStringW - #define WUSysMessage WUSysMessageW - #define WUFormat WUFormatW -#else - #define CStdString CStdStringA - #define WUSysMessage WUSysMessageA - #define WUFormat WUFormatA -#endif - -// ...and some shorter names for the space-efficient - -#define WUSysMsg WUSysMessage -#define WUSysMsgA WUSysMessageA -#define WUSysMsgW WUSysMessageW -#define WUFmtA WUFormatA -#define WUFmtW WUFormatW -#define WUFmt WUFormat -#define WULastErrMsg() WUSysMessage(::GetLastError()) -#define WULastErrMsgA() WUSysMessageA(::GetLastError()) -#define WULastErrMsgW() WUSysMessageW(::GetLastError()) - - -// ----------------------------------------------------------------------------- -// FUNCTIONAL COMPARATORS: -// REMARKS: -// These structs are derived from the std::binary_function template. They -// give us functional classes (which may be used in Standard C++ Library -// collections and algorithms) that perform case-insensitive comparisons of -// CStdString objects. This is useful for maps in which the key may be the -// proper string but in the wrong case. -// ----------------------------------------------------------------------------- -#define StdStringLessNoCaseW SSLNCW // avoid VC compiler warning 4786 -#define StdStringEqualsNoCaseW SSENCW -#define StdStringLessNoCaseA SSLNCA -#define StdStringEqualsNoCaseA SSENCA - -#ifdef UNICODE - #define StdStringLessNoCase SSLNCW - #define StdStringEqualsNoCase SSENCW -#else - #define StdStringLessNoCase SSLNCA - #define StdStringEqualsNoCase SSENCA -#endif - -struct StdStringLessNoCaseW - : std::binary_function -{ - inline - bool operator()(const CStdStringW& sLeft, const CStdStringW& sRight) const - { return ssicmp(sLeft.c_str(), sRight.c_str()) < 0; } -}; -struct StdStringEqualsNoCaseW - : std::binary_function -{ - inline - bool operator()(const CStdStringW& sLeft, const CStdStringW& sRight) const - { return ssicmp(sLeft.c_str(), sRight.c_str()) == 0; } -}; -struct StdStringLessNoCaseA - : std::binary_function -{ - inline - bool operator()(const CStdStringA& sLeft, const CStdStringA& sRight) const - { return ssicmp(sLeft.c_str(), sRight.c_str()) < 0; } -}; -struct StdStringEqualsNoCaseA - : std::binary_function -{ - inline - bool operator()(const CStdStringA& sLeft, const CStdStringA& sRight) const - { return ssicmp(sLeft.c_str(), sRight.c_str()) == 0; } -}; - -// If we had to define our own version of TRACE above, get rid of it now - -#ifdef TRACE_DEFINED_HERE - #undef TRACE - #undef TRACE_DEFINED_HERE -#endif - - -#endif // #ifndef STDSTRING_H \ No newline at end of file diff --git a/MAC_SDK/Source/Shared/Unicows.cpp b/MAC_SDK/Source/Shared/Unicows.cpp deleted file mode 100644 index e7131f1..0000000 --- a/MAC_SDK/Source/Shared/Unicows.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include - -HMODULE LoadUnicowsProc(void) -{ - HMODULE hModule = LoadLibraryA("unicows.dll"); - if (hModule == NULL) - { - MessageBoxA(NULL, "The Microsoft Layer for Unicode failed to initialize. Please re-install.", "Unicode Failure", MB_OK | MB_ICONERROR); - _exit(-1); - } - - return hModule; -} - -extern "C" -{ - extern FARPROC _PfnLoadUnicows = (FARPROC) &LoadUnicowsProc; -} diff --git a/MAC_SDK/Source/Shared/WAVInfoDialog.cpp b/MAC_SDK/Source/Shared/WAVInfoDialog.cpp deleted file mode 100644 index 30c3540..0000000 --- a/MAC_SDK/Source/Shared/WAVInfoDialog.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include "All.h" - -#include "WAVInfoDialog.h" -#include "WAVInputSource.h" -#include "CharacterHelper.h" - -/*************************************************************************************** -The dialog component ID's -***************************************************************************************/ -#define FILE_NAME_STATIC 1000 - -#define FILE_SIZE_STATIC 2000 -#define TRACK_LENGTH_STATIC 2001 -#define AUDIO_BYTES_STATIC 2002 -#define HEADER_BYTES_STATIC 2003 -#define TERMINATING_BYTES_STATIC 2004 - -#define SAMPLE_RATE_STATIC 3000 -#define CHANNELS_STATIC 3001 -#define BITS_PER_SAMPLE_STATIC 3002 - -#define OK_BUTTON 4000 - -/*************************************************************************************** -Global pointer to this instance -***************************************************************************************/ -CWAVInfoDialog * g_pWAVInfoDialog; - - -/*************************************************************************************** -Construction / destruction -***************************************************************************************/ -CWAVInfoDialog::CWAVInfoDialog() -{ - g_pWAVInfoDialog = NULL; -} - -CWAVInfoDialog::~CWAVInfoDialog() -{ - -} - -/*************************************************************************************** -Display the file info dialog -***************************************************************************************/ -long CWAVInfoDialog::ShowWAVInfoDialog(const str_utf16 * pFilename, HINSTANCE hInstance, const str_utf16 * lpTemplateName, HWND hWndParent) -{ - //only allow one instance at a time - if (g_pWAVInfoDialog != NULL) - { - return -1; - } - - _tcscpy(m_cFileName, pFilename); - g_pWAVInfoDialog = this; - - DialogBoxParam(hInstance, lpTemplateName, hWndParent, (DLGPROC) DialogProc, 0); - - g_pWAVInfoDialog = NULL; - return 0; -} - -/*************************************************************************************** -Initialize the dialog -***************************************************************************************/ -long CWAVInfoDialog::InitDialog(HWND hDlg) -{ - // analyze the WAV - WAVEFORMATEX wfeWAV; - int nTotalBlocks = 0; - int nHeaderBytes = 0; - int nTerminatingBytes = 0; - int nErrorCode = 0; - - CWAVInputSource WAVInfo(m_cFileName, &wfeWAV, &nTotalBlocks, &nHeaderBytes, &nTerminatingBytes, &nErrorCode); - if (nErrorCode != 0) - return nErrorCode; - - int nAudioBytes = nTotalBlocks * wfeWAV.nBlockAlign; - - // set info - TCHAR cTemp[1024] = { 0 }; - - SetDlgItemText(hDlg, FILE_NAME_STATIC, m_cFileName); - - _stprintf(cTemp, _T("Sample Rate: %d"), wfeWAV.nSamplesPerSec); - SetDlgItemText(hDlg, SAMPLE_RATE_STATIC, cTemp); - - _stprintf(cTemp, _T("Channels: %d"), wfeWAV.nChannels); - SetDlgItemText(hDlg, CHANNELS_STATIC, cTemp); - - _stprintf(cTemp, _T("Bits Per Sample: %d"), int(wfeWAV.wBitsPerSample)); - SetDlgItemText(hDlg, BITS_PER_SAMPLE_STATIC, cTemp); - - int nSeconds = nAudioBytes / wfeWAV.nAvgBytesPerSec; 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); - - _stprintf(cTemp, _T("Audio Bytes: %d"), nAudioBytes); - SetDlgItemText(hDlg, AUDIO_BYTES_STATIC, cTemp); - - _stprintf(cTemp, _T("Header Bytes: %d"), nHeaderBytes); - SetDlgItemText(hDlg, HEADER_BYTES_STATIC, cTemp); - - _stprintf(cTemp, _T("Terminating Bytes: %d"), nTerminatingBytes); - SetDlgItemText(hDlg, TERMINATING_BYTES_STATIC, cTemp); - - _stprintf(cTemp, _T("File Size: %.2f MB"), float(nAudioBytes + nHeaderBytes + nTerminatingBytes) / float(1024 * 1024)); - SetDlgItemText(hDlg, FILE_SIZE_STATIC, cTemp); - - return 0; -} - -/*************************************************************************************** -The dialog procedure -***************************************************************************************/ -LRESULT CALLBACK CWAVInfoDialog::DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - int wmID, wmEvent; - long RetVal; - - switch (message) - { - case WM_INITDIALOG: - //fill in the info on initialization - RetVal = g_pWAVInfoDialog->InitDialog(hDlg); - 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 OK_BUTTON: - EndDialog(hDlg, 0); - return TRUE; - break; - } - break; - case WM_CLOSE: - EndDialog(hDlg, 0); - return TRUE; - break; - } - - return FALSE; -} - - diff --git a/MAC_SDK/Source/Shared/WAVInfoDialog.h b/MAC_SDK/Source/Shared/WAVInfoDialog.h deleted file mode 100644 index 31fe1c5..0000000 --- a/MAC_SDK/Source/Shared/WAVInfoDialog.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef APE_WAVINFODIALOG_H -#define APE_WAVINFODIALOG_H - -BOOL CALLBACK FileInfoDialogProcedureA(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); - -class CWAVInfoDialog -{ -public: - - CWAVInfoDialog(); - ~CWAVInfoDialog(); - - long ShowWAVInfoDialog(const str_utf16 * pFilename, HINSTANCE hInstance, const str_utf16 * lpTemplateName, HWND hWndParent); - -private: - - static LRESULT CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); - long InitDialog(HWND hDlg); - TCHAR m_cFileName[MAX_PATH]; -}; - -#endif // #ifndef APE_WAVINFODIALOG_H diff --git a/MAC_SDK/Source/Shared/WinFileIO.cpp b/MAC_SDK/Source/Shared/WinFileIO.cpp deleted file mode 100644 index 5629825..0000000 --- a/MAC_SDK/Source/Shared/WinFileIO.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include "All.h" - -#ifdef IO_USE_WIN_FILE_IO - -#include "WinFileIO.h" -#include -#include "CharacterHelper.h" - -CWinFileIO::CWinFileIO() -{ - m_hFile = INVALID_HANDLE_VALUE; - memset(m_cFileName, 0, MAX_PATH); - m_bReadOnly = FALSE; -} - -CWinFileIO::~CWinFileIO() -{ - Close(); -} - -int CWinFileIO::Open(const wchar_t * pName, int fReadonly) -{ - Close(); - - #ifdef _UNICODE - CSmartPtr spName((wchar_t *) pName, TRUE, FALSE); - #else - CSmartPtr spName(GetANSIFromUTF16(pName), TRUE); - #endif - - m_hFile = INVALID_HANDLE_VALUE; - if (!fReadonly) - m_hFile = ::CreateFile(spName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (m_hFile == INVALID_HANDLE_VALUE) - { - m_hFile = ::CreateFile(spName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (m_hFile == INVALID_HANDLE_VALUE) - { - return -1; - } - else - { - m_bReadOnly = TRUE; - } - } - else - { - m_bReadOnly = FALSE; - } - - wcscpy(m_cFileName, pName); - - return 0; -} - -int CWinFileIO::Close() -{ - SAFE_FILE_CLOSE(m_hFile); - - return 0; -} - -int CWinFileIO::Read(void * pBuffer, unsigned int nBytesToRead, unsigned int * pBytesRead) -{ - unsigned int nTotalBytesRead = 0; - int nBytesLeft = nBytesToRead; - BOOL bRetVal = TRUE; - unsigned char * pucBuffer = (unsigned char *) pBuffer; - - *pBytesRead = 1; - while ((nBytesLeft > 0) && (*pBytesRead > 0) && bRetVal) - { - bRetVal = ::ReadFile(m_hFile, &pucBuffer[nBytesToRead - nBytesLeft], nBytesLeft, (unsigned long *) pBytesRead, NULL); - if (bRetVal == TRUE) - { - nBytesLeft -= *pBytesRead; - nTotalBytesRead += *pBytesRead; - } - } - - *pBytesRead = nTotalBytesRead; - - return (bRetVal == FALSE) ? ERROR_IO_READ : 0; -} - -int CWinFileIO::Write(const void * pBuffer, unsigned int nBytesToWrite, unsigned int * pBytesWritten) -{ - BOOL bRetVal = WriteFile(m_hFile, pBuffer, nBytesToWrite, (unsigned long *) pBytesWritten, NULL); - - if ((bRetVal == 0) || (*pBytesWritten != nBytesToWrite)) - return ERROR_IO_WRITE; - else - return 0; -} - -int CWinFileIO::Seek(int nDistance, unsigned int nMoveMode) -{ - SetFilePointer(m_hFile, nDistance, NULL, nMoveMode); - return 0; -} - -int CWinFileIO::SetEOF() -{ - BOOL bRetVal = SetEndOfFile(m_hFile); - if (bRetVal == FALSE) - { - return -1; - } - else - { - return 0; - } -} - -int CWinFileIO::GetPosition() -{ - return SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT); -} - -int CWinFileIO::GetSize() -{ - return GetFileSize(m_hFile, NULL); -} - -int CWinFileIO::GetName(wchar_t * pBuffer) -{ - wcscpy(pBuffer, m_cFileName); - return 0; -} - -int CWinFileIO::Create(const wchar_t * pName) -{ - Close(); - - #ifdef _UNICODE - CSmartPtr spName((wchar_t *) pName, TRUE, FALSE); - #else - CSmartPtr spName(GetANSIFromUTF16(pName), TRUE); - #endif - - m_hFile = CreateFile(spName, GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (m_hFile == INVALID_HANDLE_VALUE) { return -1; } - - m_bReadOnly = FALSE; - - wcscpy(m_cFileName, pName); - - return 0; -} - -int CWinFileIO::Delete() -{ - Close(); - - #ifdef _UNICODE - CSmartPtr spName(m_cFileName, TRUE, FALSE); - #else - CSmartPtr spName(GetANSIFromUTF16(m_cFileName), TRUE); - #endif - - return DeleteFile(spName) ? 0 : -1; -} - -#endif // #ifdef IO_USE_WIN_FILE_IO diff --git a/MAC_SDK/Source/Shared/WinFileIO.h b/MAC_SDK/Source/Shared/WinFileIO.h deleted file mode 100644 index e633dc5..0000000 --- a/MAC_SDK/Source/Shared/WinFileIO.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifdef IO_USE_WIN_FILE_IO - -#ifndef _winfileio_h_ -#define _winfileio_h_ - -#include "IO.h" - -class CWinFileIO : public CIO -{ -public: - - // construction / destruction - CWinFileIO(); - ~CWinFileIO(); - - // open / close - int Open(const wchar_t * pName, int fReadonly = 0); - int Close(); - - // read / write - int Read(void * pBuffer, unsigned int nBytesToRead, unsigned int * pBytesRead); - int Write(const void * pBuffer, unsigned int nBytesToWrite, unsigned int * pBytesWritten); - - // seek - int Seek(int nDistance, unsigned int nMoveMode); - - // other functions - int SetEOF(); - - // creation / destruction - int Create(const wchar_t * pName); - int Delete(); - - // attributes - int GetPosition(); - int GetSize(); - int GetName(wchar_t * pBuffer); - -private: - - HANDLE m_hFile; - wchar_t m_cFileName[MAX_PATH]; - BOOL m_bReadOnly; -}; - - -#endif //_winfileio_h_ - -#endif //IO_USE_WIN_FILE_IO \ No newline at end of file diff --git a/ThirdParty/MAC_SDK b/ThirdParty/MAC_SDK new file mode 160000 index 0000000..bb37bfa --- /dev/null +++ b/ThirdParty/MAC_SDK @@ -0,0 +1 @@ +Subproject commit bb37bfafa4d23f2df6d7767ca937c540bc422ad0 diff --git a/ThirdPartyDebug/x64/MACLib.lib b/ThirdPartyDebug/x64/MACLib.lib new file mode 100644 index 0000000000000000000000000000000000000000..1e9760b723760a469a2b3462fec1a9b6b293e4b0 GIT binary patch literal 1792320 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

Q32 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 >0JBLKXJ35DW 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

G$Y^QfEl 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 S*Fl%Q#PA0!+hb4N~~osaNIJqA!Z0-3*G9CjZf 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%0AS)v*G0+NDuP;*&ug-#6WjwBfA46<|TnhA0WSh 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 literal 0 HcmV?d00001