diff --git a/Avara.msvc/Avara.vcxproj b/Avara.msvc/Avara.vcxproj index b022293d..471f78e9 100644 --- a/Avara.msvc/Avara.vcxproj +++ b/Avara.msvc/Avara.vcxproj @@ -143,7 +143,7 @@ _WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;NANOGUI_GLAD;%(PreprocessorDefinitions) true stdcpp17 - ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories) + ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories) false true stdc17 @@ -171,7 +171,7 @@ true NDEBUG;_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;NANOGUI_GLAD;%(PreprocessorDefinitions) true - ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8; + ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8; true stdcpp17 stdc17 @@ -211,4 +211,4 @@ - \ No newline at end of file + diff --git a/Avara.msvc/AvaraCore.vcxproj b/Avara.msvc/AvaraCore.vcxproj index 9117ed44..1bdee7f7 100644 --- a/Avara.msvc/AvaraCore.vcxproj +++ b/Avara.msvc/AvaraCore.vcxproj @@ -123,7 +123,7 @@ _WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;_DEBUG;NANOGUI_GLAD;%(PreprocessorDefinitions) true stdcpp17 - ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories) + ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories) false true @@ -148,7 +148,7 @@ true _WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;NDEBUG;NANOGUI_GLAD;%(PreprocessorDefinitions) true - ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories) + ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories) stdcpp17 stdc17 true @@ -180,7 +180,6 @@ - @@ -315,9 +314,6 @@ - - - @@ -391,7 +387,6 @@ - @@ -507,9 +502,6 @@ - - - @@ -546,4 +538,4 @@ - \ No newline at end of file + diff --git a/Avara.msvc/AvaraCore.vcxproj.filters b/Avara.msvc/AvaraCore.vcxproj.filters index e12ef1b1..a7b11584 100644 --- a/Avara.msvc/AvaraCore.vcxproj.filters +++ b/Avara.msvc/AvaraCore.vcxproj.filters @@ -66,9 +66,6 @@ Header Files - - Header Files - Header Files @@ -165,21 +162,12 @@ Header Files - - Header Files - - - Header Files - Header Files Header Files - - Header Files - Header Files @@ -959,9 +947,6 @@ Source Files - - Source Files - Source Files @@ -1007,15 +992,6 @@ Source Files - - Source Files - - - Source Files - - - Source Files - Source Files @@ -1140,4 +1116,4 @@ Source Files - \ No newline at end of file + diff --git a/Avara.msvc/Tests.vcxproj b/Avara.msvc/Tests.vcxproj index 5bdbfac0..97377b77 100644 --- a/Avara.msvc/Tests.vcxproj +++ b/Avara.msvc/Tests.vcxproj @@ -115,7 +115,7 @@ _WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;_DEBUG;NANOGUI_GLAD;%(PreprocessorDefinitions) true stdcpp17 - ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories) + ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories) false true @@ -140,7 +140,7 @@ true _WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_WARNINGS;NDEBUG;NANOGUI_GLAD;%(PreprocessorDefinitions) true - ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\src\util\huffman;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories) + ..\src\audio;..\src\assets;..\src\base;..\src\bsp;..\src\compat;..\src\game;..\src\gui;..\src\level;..\src\net;..\src\render;..\src\tui;..\src\util;..\vendor\;..\vendor\nanogui;..\vendor\nanovg;..\vendor\pugixml;..\vendor\utf8;%(AdditionalIncludeDirectories) true stdcpp17 stdc17 @@ -167,4 +167,4 @@ - \ No newline at end of file + diff --git a/Avara.xcodeproj/project.pbxproj b/Avara.xcodeproj/project.pbxproj index 091dc9b5..a5483250 100644 --- a/Avara.xcodeproj/project.pbxproj +++ b/Avara.xcodeproj/project.pbxproj @@ -58,7 +58,6 @@ E517F056299713DB0036B206 /* CSoundHub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C7329895118007A875D /* CSoundHub.cpp */; }; E517F057299713DB0036B206 /* CSoundMixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C7729895118007A875D /* CSoundMixer.cpp */; }; E517F058299713DB0036B206 /* DopplerPlug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C7429895118007A875D /* DopplerPlug.cpp */; }; - E517F05A299713DB0036B206 /* CDirectObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9D29895118007A875D /* CDirectObject.cpp */; }; E517F05B299713DB0036B206 /* CTagBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9A29895118007A875D /* CTagBase.cpp */; }; E517F05C299713DB0036B206 /* CBSPPart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C6829895118007A875D /* CBSPPart.cpp */; }; E517F05D299713DB0036B206 /* CBSPWorld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C6129895118007A875D /* CBSPWorld.cpp */; }; @@ -162,9 +161,6 @@ E517F0C2299713DB0036B206 /* CStringDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BC029895118007A875D /* CStringDictionary.cpp */; }; E517F0C3299713DB0036B206 /* Debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBF29895118007A875D /* Debug.cpp */; }; E517F0C4299713DB0036B206 /* FastMat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBD29895118007A875D /* FastMat.cpp */; }; - E517F0C5299713DB0036B206 /* CHuffProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB529895118007A875D /* CHuffProcessor.cpp */; }; - E517F0C6299713DB0036B206 /* CAbstractPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB629895118007A875D /* CAbstractPipe.cpp */; }; - E517F0C7299713DB0036B206 /* CAbstractHuffPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB729895118007A875D /* CAbstractHuffPipe.cpp */; }; E517F0CA299713DB0036B206 /* RamFiles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BC129895118007A875D /* RamFiles.cpp */; }; E517F0CB299713DB0036B206 /* csscolorparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D3F29895123007A875D /* csscolorparser.cpp */; }; E517F0CC299713DB0036B206 /* glm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890E0D29895123007A875D /* glm.cpp */; }; @@ -213,9 +209,6 @@ E5890CA629895118007A875D /* CProtoControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BA729895118007A875D /* CProtoControl.cpp */; }; E5890CA729895118007A875D /* CRC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BAA29895118007A875D /* CRC.cpp */; }; E5890CA829895118007A875D /* Beeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB329895118007A875D /* Beeper.cpp */; }; - E5890CA929895118007A875D /* CHuffProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB529895118007A875D /* CHuffProcessor.cpp */; }; - E5890CAA29895118007A875D /* CAbstractPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB629895118007A875D /* CAbstractPipe.cpp */; }; - E5890CAB29895118007A875D /* CAbstractHuffPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB729895118007A875D /* CAbstractHuffPipe.cpp */; }; E5890CAD29895118007A875D /* FastMat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBD29895118007A875D /* FastMat.cpp */; }; E5890CAE29895118007A875D /* Debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBF29895118007A875D /* Debug.cpp */; }; E5890CAF29895118007A875D /* CStringDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BC029895118007A875D /* CStringDictionary.cpp */; }; @@ -315,7 +308,6 @@ E5890D1129895118007A875D /* LevelLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9329895118007A875D /* LevelLoader.cpp */; }; E5890D1229895118007A875D /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9629895118007A875D /* Parser.cpp */; }; E5890D1429895118007A875D /* CTagBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9A29895118007A875D /* CTagBase.cpp */; }; - E5890D1529895118007A875D /* CDirectObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9D29895118007A875D /* CDirectObject.cpp */; }; E5890EEB29895124007A875D /* csscolorparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D3F29895123007A875D /* csscolorparser.cpp */; }; E5890EEC29895124007A875D /* widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D4729895123007A875D /* widget.cpp */; }; E5890EED29895124007A875D /* colorcombobox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D4829895123007A875D /* colorcombobox.cpp */; }; @@ -366,7 +358,6 @@ E5A219C32DC59135007D54FF /* CSoundMixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C7729895118007A875D /* CSoundMixer.cpp */; }; E5A219C42DC59135007D54FF /* DopplerPlug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C7429895118007A875D /* DopplerPlug.cpp */; }; E5A219C52DC59135007D54FF /* OggFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94924EAE2B3A894900197378 /* OggFile.cpp */; }; - E5A219C72DC59135007D54FF /* CDirectObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9D29895118007A875D /* CDirectObject.cpp */; }; E5A219C82DC59135007D54FF /* CTagBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C9A29895118007A875D /* CTagBase.cpp */; }; E5A219C92DC59135007D54FF /* CCompoundShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 948DF4152DA365CB007FEFDE /* CCompoundShape.cpp */; }; E5A219CA2DC59135007D54FF /* CBSPPart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890C6829895118007A875D /* CBSPPart.cpp */; }; @@ -480,9 +471,6 @@ E5A21A372DC59135007D54FF /* CStringDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BC029895118007A875D /* CStringDictionary.cpp */; }; E5A21A382DC59135007D54FF /* Debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBF29895118007A875D /* Debug.cpp */; }; E5A21A392DC59135007D54FF /* FastMat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BBD29895118007A875D /* FastMat.cpp */; }; - E5A21A3A2DC59135007D54FF /* CHuffProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB529895118007A875D /* CHuffProcessor.cpp */; }; - E5A21A3B2DC59135007D54FF /* CAbstractPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB629895118007A875D /* CAbstractPipe.cpp */; }; - E5A21A3C2DC59135007D54FF /* CAbstractHuffPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BB729895118007A875D /* CAbstractHuffPipe.cpp */; }; E5A21A3F2DC59135007D54FF /* RamFiles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890BC129895118007A875D /* RamFiles.cpp */; }; E5A21A402DC59135007D54FF /* csscolorparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D3F29895123007A875D /* csscolorparser.cpp */; }; E5A21A412DC59135007D54FF /* button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5890D4C29895123007A875D /* button.cpp */; }; @@ -658,12 +646,6 @@ E5890BB129895118007A875D /* SlidingHistogram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlidingHistogram.h; sourceTree = ""; }; E5890BB229895118007A875D /* CRC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CRC.h; sourceTree = ""; }; E5890BB329895118007A875D /* Beeper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Beeper.cpp; sourceTree = ""; }; - E5890BB529895118007A875D /* CHuffProcessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CHuffProcessor.cpp; sourceTree = ""; }; - E5890BB629895118007A875D /* CAbstractPipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAbstractPipe.cpp; sourceTree = ""; }; - E5890BB729895118007A875D /* CAbstractHuffPipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAbstractHuffPipe.cpp; sourceTree = ""; }; - E5890BB829895118007A875D /* CHuffProcessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHuffProcessor.h; sourceTree = ""; }; - E5890BBA29895118007A875D /* CAbstractPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAbstractPipe.h; sourceTree = ""; }; - E5890BBC29895118007A875D /* CAbstractHuffPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAbstractHuffPipe.h; sourceTree = ""; }; E5890BBD29895118007A875D /* FastMat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FastMat.cpp; sourceTree = ""; }; E5890BBF29895118007A875D /* Debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Debug.cpp; sourceTree = ""; }; E5890BC029895118007A875D /* CStringDictionary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CStringDictionary.cpp; sourceTree = ""; }; @@ -870,10 +852,8 @@ E5890C9429895118007A875D /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = ""; }; E5890C9529895118007A875D /* LevelLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LevelLoader.h; sourceTree = ""; }; E5890C9629895118007A875D /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Parser.cpp; sourceTree = ""; }; - E5890C9829895118007A875D /* CDirectObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDirectObject.h; sourceTree = ""; }; E5890C9A29895118007A875D /* CTagBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTagBase.cpp; sourceTree = ""; }; E5890C9B29895118007A875D /* CTagBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CTagBase.h; sourceTree = ""; }; - E5890C9D29895118007A875D /* CDirectObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDirectObject.cpp; sourceTree = ""; }; E5890D1729895123007A875D /* httplib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = httplib.h; sourceTree = ""; }; E5890D1829895123007A875D /* cute_files.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cute_files.h; sourceTree = ""; }; E5890D1929895123007A875D /* json.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = json.hpp; sourceTree = ""; }; @@ -1219,7 +1199,6 @@ E5890ED429895124007A875D /* fontstash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontstash.h; sourceTree = ""; }; E5890ED529895124007A875D /* nanovg_gl_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nanovg_gl_utils.h; sourceTree = ""; }; E5890ED729895124007A875D /* nanovg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nanovg.c; sourceTree = ""; }; - E5890ED829895124007A875D /* AudioFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioFile.h; sourceTree = ""; }; E5890ED929895124007A875D /* stb_vorbis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stb_vorbis.h; sourceTree = ""; }; E5890EDA29895124007A875D /* utf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf8.h; sourceTree = ""; }; E5890EDB29895124007A875D /* csscolorparser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = csscolorparser.hpp; sourceTree = ""; }; @@ -1419,7 +1398,6 @@ E5890BBD29895118007A875D /* FastMat.cpp */, E5890BAF29895118007A875D /* FastMat.h */, E5890BAE29895118007A875D /* GitVersion.h */, - E5890BB429895118007A875D /* huffman */, E5890BC129895118007A875D /* RamFiles.cpp */, E5890BAD29895118007A875D /* RamFiles.h */, E5890BC229895118007A875D /* RayHit.h */, @@ -1432,19 +1410,6 @@ path = util; sourceTree = ""; }; - E5890BB429895118007A875D /* huffman */ = { - isa = PBXGroup; - children = ( - E5890BBC29895118007A875D /* CAbstractHuffPipe.h */, - E5890BB729895118007A875D /* CAbstractHuffPipe.cpp */, - E5890BBA29895118007A875D /* CAbstractPipe.h */, - E5890BB629895118007A875D /* CAbstractPipe.cpp */, - E5890BB829895118007A875D /* CHuffProcessor.h */, - E5890BB529895118007A875D /* CHuffProcessor.cpp */, - ); - path = huffman; - sourceTree = ""; - }; E5890BC729895118007A875D /* tui */ = { isa = PBXGroup; children = ( @@ -1706,8 +1671,6 @@ E5890C9729895118007A875D /* base */ = { isa = PBXGroup; children = ( - E5890C9D29895118007A875D /* CDirectObject.cpp */, - E5890C9829895118007A875D /* CDirectObject.h */, E5890C9A29895118007A875D /* CTagBase.cpp */, E5890C9B29895118007A875D /* CTagBase.h */, ); @@ -2390,7 +2353,6 @@ E517F057299713DB0036B206 /* CSoundMixer.cpp in Sources */, E517F058299713DB0036B206 /* DopplerPlug.cpp in Sources */, 948CBF152B335A1400147E80 /* BaseAssetStorage.cpp in Sources */, - E517F05A299713DB0036B206 /* CDirectObject.cpp in Sources */, E517F05B299713DB0036B206 /* CTagBase.cpp in Sources */, E517F05C299713DB0036B206 /* CBSPPart.cpp in Sources */, E517F05D299713DB0036B206 /* CBSPWorld.cpp in Sources */, @@ -2506,9 +2468,6 @@ E517F0C2299713DB0036B206 /* CStringDictionary.cpp in Sources */, E517F0C3299713DB0036B206 /* Debug.cpp in Sources */, E517F0C4299713DB0036B206 /* FastMat.cpp in Sources */, - E517F0C5299713DB0036B206 /* CHuffProcessor.cpp in Sources */, - E517F0C6299713DB0036B206 /* CAbstractPipe.cpp in Sources */, - E517F0C7299713DB0036B206 /* CAbstractHuffPipe.cpp in Sources */, E2CF30032DA88F4D002DD786 /* LegacyOpenGLRenderer.cpp in Sources */, E517F0CA299713DB0036B206 /* RamFiles.cpp in Sources */, E517F0CB299713DB0036B206 /* csscolorparser.cpp in Sources */, @@ -2573,7 +2532,6 @@ E5890CBB29895118007A875D /* CDome.cpp in Sources */, E5890F1929895124007A875D /* glad.c in Sources */, E5890CFA29895118007A875D /* CSmartBox.cpp in Sources */, - E5890D1529895118007A875D /* CDirectObject.cpp in Sources */, E2CD7FAC2DB5BE1D00C3665F /* LevelInfo.cpp in Sources */, E5890CC729895118007A875D /* LinkLoose.cpp in Sources */, E5890F0329895124007A875D /* textbox.cpp in Sources */, @@ -2642,7 +2600,6 @@ E5890F0729895124007A875D /* desccombobox.cpp in Sources */, E5890CDF29895118007A875D /* CLogicDistributor.cpp in Sources */, E5890CC029895118007A875D /* CGoal.cpp in Sources */, - E5890CA929895118007A875D /* CHuffProcessor.cpp in Sources */, E5890EF729895124007A875D /* popup.cpp in Sources */, 9465BFD72B30EF680050681C /* PackageManifest.cpp in Sources */, E5890CBA29895118007A875D /* CWeapon.cpp in Sources */, @@ -2674,12 +2631,10 @@ E5890EF029895124007A875D /* vscrollpanel.cpp in Sources */, E5890CCF29895118007A875D /* CAbstractPlayer.cpp in Sources */, E5890CE329895118007A875D /* CGrenade.cpp in Sources */, - E5890CAB29895118007A875D /* CAbstractHuffPipe.cpp in Sources */, E5890CAD29895118007A875D /* FastMat.cpp in Sources */, E5890EFC29895124007A875D /* tabwidget.cpp in Sources */, E5890CD829895118007A875D /* CWallDoor.cpp in Sources */, E5890CBF29895118007A875D /* CAbstractActor.cpp in Sources */, - E5890CAA29895118007A875D /* CAbstractPipe.cpp in Sources */, E5890F0929895124007A875D /* stb_vorbis.c in Sources */, 6025AE4E2C255E6A00A57EFB /* LegacyOpenGLRenderer.cpp in Sources */, E5890D0529895118007A875D /* CSoundMixer.cpp in Sources */, @@ -2739,7 +2694,6 @@ E5A219C32DC59135007D54FF /* CSoundMixer.cpp in Sources */, E5A219C42DC59135007D54FF /* DopplerPlug.cpp in Sources */, E5A219C52DC59135007D54FF /* OggFile.cpp in Sources */, - E5A219C72DC59135007D54FF /* CDirectObject.cpp in Sources */, E5A219C82DC59135007D54FF /* CTagBase.cpp in Sources */, E5A219C92DC59135007D54FF /* CCompoundShape.cpp in Sources */, E5A219CA2DC59135007D54FF /* CBSPPart.cpp in Sources */, @@ -2855,9 +2809,6 @@ E5A21A372DC59135007D54FF /* CStringDictionary.cpp in Sources */, E5A21A382DC59135007D54FF /* Debug.cpp in Sources */, E5A21A392DC59135007D54FF /* FastMat.cpp in Sources */, - E5A21A3A2DC59135007D54FF /* CHuffProcessor.cpp in Sources */, - E5A21A3B2DC59135007D54FF /* CAbstractPipe.cpp in Sources */, - E5A21A3C2DC59135007D54FF /* CAbstractHuffPipe.cpp in Sources */, E5A21A3F2DC59135007D54FF /* RamFiles.cpp in Sources */, E5A21A402DC59135007D54FF /* csscolorparser.cpp in Sources */, E5A21A412DC59135007D54FF /* button.cpp in Sources */, diff --git a/src/audio/CBasicSound.h b/src/audio/CBasicSound.h index c8d47f2a..ea7a99bf 100644 --- a/src/audio/CBasicSound.h +++ b/src/audio/CBasicSound.h @@ -8,7 +8,6 @@ */ #pragma once -#include "CDirectObject.h" #include "OggFile.h" #include "SoundSystemDefines.h" @@ -17,7 +16,7 @@ class CSoundMixer; class CSoundHub; -class CBasicSound : public CDirectObject { +class CBasicSound { public: Fixed masterVolume; int16_t volumes[2]; @@ -46,6 +45,8 @@ class CBasicSound : public CDirectObject { Boolean stopNow; // Flag to make the sound stop. Boolean distanceDelay; // Delay sound depending on position. + virtual ~CBasicSound() {} + // The following four functions will usually be overridden: virtual int16_t CalcVolume(int16_t theChannel); // Return volume virtual void WriteFrame(int16_t theChannel, int16_t volumeAllowed); diff --git a/src/audio/CSoundHub.cpp b/src/audio/CSoundHub.cpp index 36399712..fd64c237 100644 --- a/src/audio/CSoundHub.cpp +++ b/src/audio/CSoundHub.cpp @@ -11,7 +11,6 @@ #include "AssetManager.h" #include "CBasicSound.h" -#include "CHuffProcessor.h" #include "CRateSound.h" #include "CSoundMixer.h" #include "Memory.h" @@ -62,7 +61,7 @@ CBasicSound *CSoundHubImpl::Acquire(short kind) { return aSound; } -void CSoundHubImpl::ISoundHub(short numOfEachKind, short initialLinks) { +CSoundHubImpl::CSoundHubImpl(short numOfEachKind, short initialLinks) { short i, j; itsMixer = NULL; @@ -77,9 +76,6 @@ void CSoundHubImpl::ISoundHub(short numOfEachKind, short initialLinks) { muteFlag = false; - itsCompressor = new CHuffProcessor; - itsCompressor->Open(); - soundLinkStorage = NULL; firstFreeLink = NULL; @@ -87,31 +83,30 @@ void CSoundHubImpl::ISoundHub(short numOfEachKind, short initialLinks) { CreateSoundLinks(initialLinks); } -void CSoundHubImpl::AttachMixer(CSoundMixer *aMixer) { - itsMixer = aMixer; - muteFlag = itsMixer->maxChannels == 0; -} - -void CSoundHubImpl::Dispose() { +CSoundHubImpl::~CSoundHubImpl() { CBasicSound *aSound, *nextSound; short i; if (itsMixer) { - itsMixer->Dispose(); + delete itsMixer; + itsMixer = nullptr; } for (i = 0; i < hubSoundKinds; i++) { aSound = soundList[i]; while (aSound) { nextSound = aSound->nextSound; - aSound->Dispose(); + delete aSound; aSound = nextSound; } } - delete itsCompressor; DisposeSoundLinks(); - CDirectObject::Dispose(); +} + +void CSoundHubImpl::AttachMixer(CSoundMixer *aMixer) { + itsMixer = aMixer; + muteFlag = itsMixer->maxChannels == 0; } CBasicSound *CSoundHubImpl::GetSoundSampler(short kind, short resId) { @@ -243,7 +238,8 @@ Fixed* CSoundHubImpl::EarLocation() { } void CSoundHubImpl::MixerDispose() { if (itsMixer) { - itsMixer->Dispose(); + delete itsMixer; + itsMixer = nullptr; } } diff --git a/src/audio/CSoundHub.h b/src/audio/CSoundHub.h index 2b1430b8..abbe822f 100644 --- a/src/audio/CSoundHub.h +++ b/src/audio/CSoundHub.h @@ -9,7 +9,6 @@ #pragma once #include "CBasicSound.h" -#include "CDirectObject.h" #include "OggFile.h" #include "SoundSystemDefines.h" @@ -20,10 +19,11 @@ enum { hubBasic, hubRate, hubSoundKinds }; class CSoundMixer; -class CHuffProcessor; class CSoundHub { public: + virtual ~CSoundHub() {}; + virtual Fixed* EarLocation() = 0; virtual Fixed DistanceToLevelOne() = 0; virtual void MuteFlag(Boolean) = 0; @@ -45,15 +45,13 @@ class CSoundHub { virtual int ReadTime() = 0; virtual void HouseKeep() = 0; - virtual void Dispose() = 0; virtual void MixerDispose() = 0; virtual void HushFlag(bool) = 0; virtual bool Stereo() = 0; virtual bool AudioEnabled() { return true; }; }; -class CSoundHubImpl : public CDirectObject, public CSoundHub { +class CSoundHubImpl : public CSoundHub { public: - CHuffProcessor *itsCompressor; CSoundMixer *itsMixer; CBasicSound *soundList[hubSoundKinds]; @@ -61,7 +59,9 @@ class CSoundHubImpl : public CDirectObject, public CSoundHub { SoundLink *firstFreeLink; Boolean muteFlag; - virtual void ISoundHub(short numOfEachKind, short initialLinks); + CSoundHubImpl(short numOfEachKind, short initialLinks); + virtual ~CSoundHubImpl(); + virtual void AttachMixer(CSoundMixer *aMixer); virtual void CreateSound(short kind); @@ -81,7 +81,6 @@ class CSoundHubImpl : public CDirectObject, public CSoundHub { virtual void HouseKeep(); virtual void MuteFlag(Boolean); - virtual void Dispose(); virtual Fixed* EarLocation(); virtual Fixed DistanceToLevelOne(); virtual void MixerDispose(); diff --git a/src/audio/CSoundMixer.cpp b/src/audio/CSoundMixer.cpp index d2611912..c071ad89 100644 --- a/src/audio/CSoundMixer.cpp +++ b/src/audio/CSoundMixer.cpp @@ -93,7 +93,7 @@ void CSoundMixer::UpdateRightVector(Fixed *right) { newRightMeta = true; } -void CSoundMixer::ISoundMixer(Fixed sampRate, +CSoundMixer::CSoundMixer(Fixed sampRate, short maxChannelCount, short maxMixCount, Boolean stereoEnable, @@ -221,6 +221,52 @@ void CSoundMixer::ISoundMixer(Fixed sampRate, SDL_PauseAudioDevice(outputDevice, 0); } +CSoundMixer::~CSoundMixer() { + //OSErr iErr; + short i; + MixerInfo *mix; + + SDL_PauseAudioDevice(outputDevice, 1); + SDL_CloseAudioDevice(outputDevice); + + if (motionLink) { + altLink = NULL; + useAltLink = true; + motionHub->ReleaseLink(motionLink); + motionLink = NULL; + } + + mix = infoTable; + for (i = 0; i < maxChannels; i++) { + if (mix->active) + mix->active->Release(); + else if (mix->release) + mix->release->Release(); + else if (mix->intro) + mix->intro->Release(); + + mix++; + } + + if (mixBuffers[0]) { + DisposePtr((Ptr)mixBuffers[0]); + mixBuffers[0] = NULL; + } + +#define OBLITERATE(pointer) \ + if (pointer) { \ + DisposePtr((Ptr)pointer); \ + pointer = NULL; \ + } + + OBLITERATE(doubleBuffers[0]) + OBLITERATE(doubleBuffers[1]) + OBLITERATE(infoTable) + OBLITERATE(volumeLookup) + OBLITERATE(scaleLookup) + OBLITERATE(sortSpace[0]) +} + void CSoundMixer::PrepareScaleLookup() { int i; int value; @@ -254,7 +300,10 @@ void CSoundMixer::PrepareVolumeLookup(uint8_t mixerVolume /* 0-100 */) { if (sample16flag) { for (vol = 1; vol <= VOLUMERANGE; vol++) { for (samp = -SAMPLERANGE / 2; samp < SAMPLERANGE / 2; samp++) { - *dest++ = (samp * vol * mixerVolume / 100) << (16 - BITSPERSAMPLE - VOLUMEBITS); + // the below line was causing problems when samp is negative. + // each left shift is a multiplication by two. This might have saved cpu time on 68k. + //*dest++ = (samp * vol * mixerVolume / 100) << (16 - BITSPERSAMPLE - VOLUMEBITS); + *dest++ = (samp * vol * mixerVolume / 100) * (2 * (16 - BITSPERSAMPLE - VOLUMEBITS)); } } } else { @@ -277,52 +326,6 @@ void CSoundMixer::SilenceBuffers() { } } -void CSoundMixer::Dispose() { - //OSErr iErr; - short i; - MixerInfo *mix; - - SDL_PauseAudioDevice(outputDevice, 1); - SDL_CloseAudioDevice(outputDevice); - - if (motionLink) { - altLink = NULL; - useAltLink = true; - motionHub->ReleaseLink(motionLink); - motionLink = NULL; - } - - mix = infoTable; - for (i = 0; i < maxChannels; i++) { - if (mix->active) - mix->active->Release(); - else if (mix->release) - mix->release->Release(); - else if (mix->intro) - mix->intro->Release(); - - mix++; - } - - if (mixBuffers[0]) { - DisposePtr((Ptr)mixBuffers[0]); - mixBuffers[0] = NULL; - } - -#define OBLITERATE(pointer) \ - if (pointer) { \ - DisposePtr((Ptr)pointer); \ - pointer = NULL; \ - } - - OBLITERATE(doubleBuffers[0]) - OBLITERATE(doubleBuffers[1]) - OBLITERATE(infoTable) - OBLITERATE(volumeLookup) - OBLITERATE(scaleLookup) - OBLITERATE(sortSpace[0]) -} - void CSoundMixer::HouseKeep() { short i; MixerInfo *mix; diff --git a/src/audio/CSoundMixer.h b/src/audio/CSoundMixer.h index 11d4265a..29746a50 100644 --- a/src/audio/CSoundMixer.h +++ b/src/audio/CSoundMixer.h @@ -8,7 +8,6 @@ */ #pragma once -#include "CDirectObject.h" #include "FastMat.h" #include "SoundSystemDefines.h" @@ -47,7 +46,7 @@ typedef struct { Vector speed; // Linear motion } SoundMotionInfo; -class CSoundMixer : public CDirectObject { +class CSoundMixer { public: int32_t globRegister = 0; int32_t volumeMax = 0; @@ -106,13 +105,15 @@ class CSoundMixer : public CDirectObject { Boolean stereo = false; Boolean strongStereo = false; - void ISoundMixer(Fixed sampRate, + + CSoundMixer(Fixed sampRate, int16_t maxChannelCount, int16_t maxMixCount, Boolean stereoEnable, Boolean sample16Enable, Boolean interpolateEnable, Boolean openAudioDevice); + virtual ~CSoundMixer(); void SetSoundEnvironment(Fixed speedOfSound, Fixed distanceToLevelOne, int timeUnit); void SetStereoSeparation(Boolean strongFlag); @@ -130,7 +131,6 @@ class CSoundMixer : public CDirectObject { void DoubleBack(uint8_t *stream, int size); - virtual void Dispose() override; void HouseKeep(); void AddSound(CBasicSound *theSound); }; diff --git a/src/base/CDirectObject.cpp b/src/base/CDirectObject.cpp deleted file mode 100644 index fa6f2fd7..00000000 --- a/src/base/CDirectObject.cpp +++ /dev/null @@ -1,12 +0,0 @@ -/* - Copyright ©1994-1996, Juri Munkki - All rights reserved. - - File: CDirectObject.c - Created: Friday, March 11, 1994, 17:15 - Modified: Sunday, September 15, 1996, 21:38 -*/ - -#include "CDirectObject.h" - -void CDirectObject::Dispose() { delete this; } diff --git a/src/base/CDirectObject.h b/src/base/CDirectObject.h deleted file mode 100644 index ca606987..00000000 --- a/src/base/CDirectObject.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - Copyright ©1994-1996, Juri Munkki - All rights reserved. - - File: CDirectObject.h - Created: Friday, March 11, 1994, 17:14 - Modified: Tuesday, February 20, 1996, 07:20 -*/ - -#pragma once - -class CDirectObject { -public: - CDirectObject() {} - virtual ~CDirectObject() {} - - virtual void Dispose(); -}; diff --git a/src/bsp/CBSPPart.h b/src/bsp/CBSPPart.h index 33767199..191df117 100644 --- a/src/bsp/CBSPPart.h +++ b/src/bsp/CBSPPart.h @@ -9,7 +9,6 @@ #pragma once #include "ARGBColor.h" -#include "CDirectObject.h" #include "ColorManager.h" #include "FastMat.h" #include "Material.h" diff --git a/src/bsp/CBSPWorld.h b/src/bsp/CBSPWorld.h index 66d8c5d5..8768d7d3 100644 --- a/src/bsp/CBSPWorld.h +++ b/src/bsp/CBSPWorld.h @@ -10,7 +10,6 @@ #pragma once #include "CCompoundShape.h" -#include "CDirectObject.h" #include "Types.h" #include diff --git a/src/bsp/CViewParameters.h b/src/bsp/CViewParameters.h index ef75b19d..5aca56f1 100644 --- a/src/bsp/CViewParameters.h +++ b/src/bsp/CViewParameters.h @@ -11,7 +11,6 @@ #include "ARGBColor.h" #include "CBSPPart.h" -#include "CDirectObject.h" #define DEFAULT_LIGHT_COLOR 0xffffffff #define DIR_LIGHT_DISTANCE 1000.0f diff --git a/src/game/AvaraScoreInterface.h b/src/game/AvaraScoreInterface.h index 4b6ff578..b7ad86c1 100644 --- a/src/game/AvaraScoreInterface.h +++ b/src/game/AvaraScoreInterface.h @@ -77,7 +77,7 @@ typedef struct { long command; // One of ScoreInterfaceMessages long result; // Reserved for future calls that may return results. long capabilities; // Your capabilities. - Handle plugIn; // Your plug-in code handle + //Handle plugIn; // Your plug-in code handle long maxPlayers; // ksiInit sets this. (current default is 6) long maxTeams; // ksiInit sets this. (current default is 6) Doesn't include neutral team!! @@ -100,20 +100,8 @@ typedef struct { ** forever unless you are carelessly setting the resultsChanged flag ** even when the text has not changed. */ - Handle resultsHandle; - long resultsChanged; - - /* - ** Alternatively, you can draw the results yourself when you receive a - ** ksiResultsDraw call. If you add any controls to the window, you have - ** to remove them when you are closed and you have to hide them when you - ** receive a ksiResultsHide call. - */ - /* - WindowPtr resultsWindow; // Guaranteed to be valid only for hide/draw/click - Rect resultsRect; // Valid only for draw/click calls - EventRecord *theEvent; - */ + //Handle resultsHandle; + //long resultsChanged; /* ** The following parameters are valid for all calls and usually change diff --git a/src/game/CAbstractActor.h b/src/game/CAbstractActor.h index 861db8b3..6b644d9f 100644 --- a/src/game/CAbstractActor.h +++ b/src/game/CAbstractActor.h @@ -10,7 +10,6 @@ #pragma once #include "AssetManager.h" #include "CAvaraGame.h" -#include "CDirectObject.h" #include "ColorManager.h" #include "CSoundHub.h" #include "FastMat.h" diff --git a/src/game/CAbstractPlayer.h b/src/game/CAbstractPlayer.h index 1ab4488b..b2b0b18b 100644 --- a/src/game/CAbstractPlayer.h +++ b/src/game/CAbstractPlayer.h @@ -161,8 +161,8 @@ class CAbstractPlayer : public CRealMovers { // Winning/loosing: FrameNumber winFrame = 0; - Quaternion winStart = {0}; - Quaternion winEnd = {0}; + Quaternion winStart = {0, 0, 0, 0}; + Quaternion winEnd = {0, 0, 0, 0}; Boolean isOut = 0; short lives = 0; diff --git a/src/game/CAvaraGame.cpp b/src/game/CAvaraGame.cpp index b859dd82..a26d8555 100755 --- a/src/game/CAvaraGame.cpp +++ b/src/game/CAvaraGame.cpp @@ -55,8 +55,7 @@ void CAvaraGame::InitMixer(Boolean silentFlag) { soundHub->MixerDispose(); - aMixer = new CSoundMixer; - aMixer->ISoundMixer(rate22khz, 64, 8, true, true, false, soundHub->AudioEnabled()); + aMixer = new CSoundMixer(rate22khz, 64, 8, true, true, false, soundHub->AudioEnabled()); aMixer->SetStereoSeparation(true); aMixer->SetSoundEnvironment(FIX(400), FIX(5), CLASSICFRAMETIME); aMixer->SetVolume(gApplication ? gApplication->Get(kSoundVolume) : 0); @@ -85,7 +84,7 @@ void CAvaraGame::IncrementGameCounter() { } std::unique_ptr CAvaraGame::CreateNetManager() { - return std::make_unique(); + return std::make_unique(this); } CAvaraGame::CAvaraGame(FrameTime frameTime) { @@ -96,7 +95,7 @@ void CAvaraGame::IAvaraGame(CAvaraApp *theApp) { itsApp = theApp; itsNet = CreateNetManager(); - itsNet->INetManager(this); + itsNet->InitializePlayers(); itsApp->SetNet(itsNet.get()); searchCount = 0; @@ -119,11 +118,9 @@ void CAvaraGame::IAvaraGame(CAvaraApp *theApp) { InitMixer(true); - scoreKeeper = new CScoreKeeper; - scoreKeeper->IScoreKeeper(this); + scoreKeeper = new CScoreKeeper(this); - itsDepot = new CDepot; - itsDepot->IDepot(this); + itsDepot = new CDepot(this); // mapRes = GetResource(FUNMAPTYPE, FUNMAPID); @@ -151,9 +148,7 @@ void CAvaraGame::IAvaraGame(CAvaraApp *theApp) { } CSoundHub* CAvaraGame::CreateSoundHub() { - CSoundHubImpl *soundHub = new CSoundHubImpl; - soundHub->ISoundHub(32, 32); - return soundHub; + return new CSoundHubImpl(32, 32); } CAvaraGame::~CAvaraGame() { @@ -162,8 +157,8 @@ CAvaraGame::~CAvaraGame() { spectatePlayer = NULL; LevelReset(false); - scoreKeeper->Dispose(); - itsDepot->Dispose(); + delete scoreKeeper; + delete itsDepot; while (actorList) { nextActor = actorList->nextActor; @@ -178,12 +173,8 @@ CAvaraGame::~CAvaraGame() { } if (soundHub) - soundHub->Dispose(); -// if (itsNet) -// itsNet->Dispose(); - // ReleaseResource(mapRes); + delete soundHub; - // DisposePolyWorld(&itsPolyWorld); DisposePtr((Ptr)locatorTable); } diff --git a/src/game/CAvaraGame.h b/src/game/CAvaraGame.h index be07505c..d70f59e4 100644 --- a/src/game/CAvaraGame.h +++ b/src/game/CAvaraGame.h @@ -11,7 +11,6 @@ #include "AvaraDefines.h" #include "AvaraScoreInterface.h" #include "AvaraTypes.h" -#include "CDirectObject.h" #include "Types.h" #include "CNetManager.h" #include "LevelInfo.h" diff --git a/src/game/CDepot.cpp b/src/game/CDepot.cpp index 8bee74b2..db8e6244 100644 --- a/src/game/CDepot.cpp +++ b/src/game/CDepot.cpp @@ -23,7 +23,7 @@ #include "CSmartPart.h" #include "CViewParameters.h" -void CDepot::IDepot(CAvaraGame *theGame) { +CDepot::CDepot(CAvaraGame *theGame) { itsGame = theGame; ReloadParts(); @@ -35,7 +35,7 @@ void CDepot::IDepot(CAvaraGame *theGame) { CreateSlivers(); } -void CDepot::Dispose() { +CDepot::~CDepot() { short i; CSliverPart *nextSliver, *slivers; @@ -55,8 +55,6 @@ void CDepot::Dispose() { delete smartSight; delete grenadeSight; delete grenadeTop; - - CDirectObject::Dispose(); } void CDepot::EndScript() { diff --git a/src/game/CDepot.h b/src/game/CDepot.h index b0339480..331005e1 100644 --- a/src/game/CDepot.h +++ b/src/game/CDepot.h @@ -9,7 +9,6 @@ #pragma once #include "AvaraDefines.h" -#include "CDirectObject.h" #include "FastMat.h" #include "RayHit.h" @@ -31,7 +30,7 @@ class CWeapon; enum { kmiFlat, kmiTurning, kmiShuriken }; enum { kweGrenade, kweSmart }; -class CDepot : public CDirectObject { +class CDepot { public: CAvaraGame *itsGame; @@ -52,8 +51,9 @@ class CDepot : public CDirectObject { Fixed missileTurnRate; Fixed missileAcceleration; - virtual void IDepot(CAvaraGame *theGame); - virtual void Dispose(); + CDepot(CAvaraGame *theGame); + virtual ~CDepot(); + virtual void EndScript(); virtual void CreateSlivers(); diff --git a/src/game/CHUD.h b/src/game/CHUD.h index ca386344..654e8b0d 100644 --- a/src/game/CHUD.h +++ b/src/game/CHUD.h @@ -1,6 +1,5 @@ #pragma once -#include "CDirectObject.h" #include #include "CViewParameters.h" #include "CPlayerManager.h" @@ -8,7 +7,7 @@ class CAvaraGame; -class CHUD : CDirectObject { +class CHUD { public: CAvaraGame *itsGame; int images; diff --git a/src/game/CNetManager.cpp b/src/game/CNetManager.cpp index efafe7cd..09e7c00e 100644 --- a/src/game/CNetManager.cpp +++ b/src/game/CNetManager.cpp @@ -48,35 +48,22 @@ extern Fixed FRandSeed; extern Fixed NewFRandSeed(); -void CNetManager::INetManager(CAvaraGame *theGame) { - short i; - +CNetManager::CNetManager(CAvaraGame *theGame) { itsGame = theGame; readyPlayers = 0; netStatus = kNullNet; itsCommManager = std::make_unique(); - itsCommManager->ICommManager(NULLNETPACKETS); - - itsProtoControl = new CProtoControl; - itsProtoControl->IProtoControl(itsCommManager.get(), itsGame); - // theRoster = ((CAvaraApp *)gApplication)->theRosterWind; - - for (i = 0; i < kMaxAvaraPlayers; i++) { - playerTable[i] = CreatePlayerManager(i); - slotToPosition[i] = i; - positionToSlot[i] = i; - teamColors[i] = i; //(i/3) * 2; - } + itsProtoControl = new CProtoControl(itsCommManager.get(), itsGame); + activePlayersDistribution = 0; totalDistribution = 0; playerCount = 0; isConnected = false; isPlaying = false; startingGame = false; - netOwner = NULL; loaderSlot = 0; serverOptions = theGame->itsApp->Number(kServerOptionsTag); @@ -89,38 +76,34 @@ void CNetManager::INetManager(CAvaraGame *theGame) { lastLoginRefusal = 0; } -std::shared_ptr CNetManager::CreatePlayerManager(short id) { - std::shared_ptr pm = std::make_shared(); - pm->IPlayerManager(itsGame, id, this); - return pm; -} - -void CNetManager::LevelReset() { - playerCount = 0; -} -void CNetManager::Dispose() { +CNetManager::~CNetManager() { short i; for (i = 0; i < kMaxAvaraPlayers; i++) { - playerTable[i]->Dispose(); + playerTable[i] = nullptr; } - itsProtoControl->Dispose(); - itsCommManager->Dispose(); + delete itsProtoControl; + itsCommManager = nullptr; } -Boolean CNetManager::ConfirmNetChange() { - /* - CCommander *theActive; - short dItem; +std::shared_ptr CNetManager::CreatePlayerManager(short id) { + return std::make_shared(itsGame, id, this); +} - theActive = gApplication->BeginDialog(); - dItem = CautionAlert(402, NULL); - gApplication->EndDialog(theActive); +// This cannot be called from the constructor because CreatePlayerManager is virtual; the test +// implementation ends up calling the CNetManager instead. +void CNetManager::InitializePlayers() { + for (int i = 0; i < kMaxAvaraPlayers; i++) { + playerTable[i] = CreatePlayerManager(i); + slotToPosition[i] = i; + positionToSlot[i] = i; + teamColors[i] = i; //(i/3) * 2; + } +} - return dItem == 1; - */ - return true; +void CNetManager::LevelReset() { + playerCount = 0; } void CNetManager::ChangeNet(short netKind, std::string address) { @@ -133,38 +116,27 @@ void CNetManager::ChangeNet(short netKind, std::string address, std::string pass //CAvaraApp *theApp = itsGame->itsApp; if (netKind != netStatus || !isConnected) { - if (netStatus != kNullNet || !isConnected) { - if (isConnected) { - confirm = ConfirmNetChange(); - } - } - - if (confirm) { - switch (netKind) { - case kNullNet: - newManager = std::make_unique(); - newManager->ICommManager(NULLNETPACKETS); - break; - case kServerNet: { - newManager = std::make_unique(); - CUDPComm *theServer = (CUDPComm*)(newManager.get()); - theServer->IUDPComm(kMaxAvaraPlayers - 1, TCPNETPACKETS, kAvaraNetVersion, itsGame->frameTime); - theServer->StartServing(); - confirm = theServer->isConnected; - } break; - case kClientNet: - newManager = std::make_unique(); - CUDPComm *theClient = (CUDPComm *)(newManager.get()); - theClient->IUDPComm(kMaxAvaraPlayers - 1, TCPNETPACKETS, kAvaraNetVersion, itsGame->frameTime); - theClient->Connect(address, password); - confirm = theClient->isConnected; - break; - } + switch (netKind) { + case kNullNet: + newManager = std::make_unique(); + break; + case kServerNet: { + newManager = std::make_unique(kMaxAvaraPlayers - 1, TCPNETPACKETS, kAvaraNetVersion, itsGame->frameTime); + CUDPComm *theServer = (CUDPComm*)(newManager.get()); + theServer->StartServing(); + confirm = theServer->isConnected; + } break; + case kClientNet: + newManager = std::make_unique(kMaxAvaraPlayers - 1, TCPNETPACKETS, kAvaraNetVersion, itsGame->frameTime); + CUDPComm *theClient = (CUDPComm *)(newManager.get()); + theClient->Connect(address, password); + confirm = theClient->isConnected; + break; } if (confirm && newManager) { PresenceType keepPresence = playerTable[itsCommManager->myId]->Presence(); - itsCommManager->Dispose(); // send kpPacketProtocolLogout message before being destroyed + itsCommManager->Finalize(); // send kpPacketProtocolLogout message before being destroyed itsProtoControl->Detach(); itsCommManager.swap(newManager); // newManager takes place existing CCommManager which gets deleted when out of scope playerTable[itsCommManager->myId]->SetPresence(keepPresence); @@ -412,7 +384,6 @@ void CNetManager::HandleDisconnect(short slotId, short why) { if (slotId == itsCommManager->myId) { isConnected = false; - netOwner = NULL; DisconnectSome(kdEveryone); itsCommManager->SendPacket(1 << slotId, kpKillNet, 0, 0, 0, 0, 0); } else { @@ -715,6 +686,7 @@ void CNetManager::ResumeGame() { // process packets until we receive all the kpStartSynch messages (with kLActive status) ProcessQueue(); + // Do we need this? // itsGame->itsApp->DoUpdate(); diff --git a/src/game/CNetManager.h b/src/game/CNetManager.h index 79232e96..57913087 100644 --- a/src/game/CNetManager.h +++ b/src/game/CNetManager.h @@ -11,7 +11,6 @@ #include "AvaraDefines.h" #include "ColorManager.h" #include "CCommManager.h" -#include "CDirectObject.h" #include "KeyFuncs.h" //#include "LevelScoreRecord.h" #include "PlayerConfig.h" @@ -68,12 +67,11 @@ typedef union } BlockAndValue; */ -class CNetManager : public CDirectObject { +class CNetManager { public: CAvaraGame *itsGame; std::unique_ptr itsCommManager; CProtoControl *itsProtoControl; - // CRosterWindow *theRoster; short playerCount; std::shared_ptr playerTable[kMaxAvaraPlayers]; @@ -88,7 +86,6 @@ class CNetManager : public CDirectObject { uint16_t startPlayersDistribution; uint16_t totalDistribution; short netStatus; - CDirectObject *netOwner; short deadOrDonePlayers; Boolean isConnected; Boolean isPlaying; @@ -126,12 +123,12 @@ class CNetManager : public CDirectObject { //char msgBuffer[kMaxChatMessageBufferLen]; std::vector msgBuffer; - virtual ~CNetManager() { Dispose(); }; - virtual void INetManager(CAvaraGame *theGame); + CNetManager(CAvaraGame *theGame); + virtual ~CNetManager(); + virtual std::shared_ptr CreatePlayerManager(short); + virtual void InitializePlayers(); virtual void LevelReset(); - virtual void Dispose(); - virtual Boolean ConfirmNetChange(); virtual void ChangeNet(short netKind, std::string address); virtual void ChangeNet(short netKind, std::string address, std::string password); diff --git a/src/game/CPlayerManager.cpp b/src/game/CPlayerManager.cpp index 55de91c0..9b8cac3c 100644 --- a/src/game/CPlayerManager.cpp +++ b/src/game/CPlayerManager.cpp @@ -36,7 +36,7 @@ CPlayerManager* CPlayerManager::theLocalPlayer; CPlayerManager* CPlayerManager::theServerPlayer; -void CPlayerManagerImpl::IPlayerManager(CAvaraGame *theGame, short id, CNetManager *aNetManager) { +CPlayerManagerImpl::CPlayerManagerImpl(CAvaraGame *theGame, short id, CNetManager *aNetManager) { // Rect *mainScreenRect; itsGame = theGame; @@ -587,10 +587,6 @@ void CPlayerManagerImpl::ViewControl() { itsPlayer->ControlViewPoint(); } -void CPlayerManagerImpl::Dispose() { - CDirectObject::Dispose(); -} - void CPlayerManagerImpl::SendResendRequest(short askCount) { if (/* theNetManager->fastTrack.addr.value || */ askCount >= 0) { theNetManager->playerTable[theNetManager->itsCommManager->myId]->ResendFrame( diff --git a/src/game/CPlayerManager.h b/src/game/CPlayerManager.h index f89f5c05..24a1463b 100644 --- a/src/game/CPlayerManager.h +++ b/src/game/CPlayerManager.h @@ -8,7 +8,6 @@ */ #pragma once -#include "CDirectObject.h" #include "ColorManager.h" #include "KeyFuncs.h" #include "PlayerConfig.h" @@ -88,7 +87,6 @@ class CPlayerManager { virtual Str255& PlayerName() = 0; virtual std::string GetPlayerName() = 0; virtual std::deque& LineBuffer() = 0; - virtual void Dispose() = 0; virtual void NetDisconnect() = 0; virtual short IsRegistered() = 0; virtual void IsRegistered(short) = 0; @@ -149,12 +147,11 @@ class CPlayerManager { virtual bool GetShowScoreboard() = 0; }; -class CPlayerManagerImpl : public CDirectObject, public CPlayerManager, public std::enable_shared_from_this { +class CPlayerManagerImpl : public CPlayerManager, public std::enable_shared_from_this { private: CAbstractPlayer *itsPlayer; CAvaraGame *itsGame; - // CRosterWindow *theRoster; CNetManager *theNetManager; Fixed randomKey; @@ -215,8 +212,9 @@ class CPlayerManagerImpl : public CDirectObject, public CPlayerManager, public s float controllerCurveExp, controllerMaxMove, controllerMultiplyX, controllerMultiplyY, controllerStickThreshold, controllerTriggerThreshold, controllerDamper; public: - virtual void IPlayerManager(CAvaraGame *theGame, short id, CNetManager *aNetManager); - + CPlayerManagerImpl(CAvaraGame *theGame, short id, CNetManager *aNetManager); + virtual ~CPlayerManagerImpl() {} + virtual void SetPlayer(CAbstractPlayer *thePlayer); virtual bool CalculateIsLocalPlayer(); @@ -235,11 +233,8 @@ class CPlayerManagerImpl : public CDirectObject, public CPlayerManager, public s virtual FunctionTable *GetFunctions(); virtual void SendResendRequest(short askCount); - virtual void Dispose(); - virtual Boolean TestKeyPressed(short funcCode); - // virtual void FlushMessageText(Boolean forceAll); virtual void RosterMessageText(short len, const char *c); virtual std::string GetChatString(int maxChars); virtual std::string GetChatLine(); @@ -277,8 +272,6 @@ class CPlayerManagerImpl : public CDirectObject, public CPlayerManager, public s virtual void StoreMugShot(Handle mugHandle); virtual Handle GetMugShot(); - // virtual void GetLoadingStatusString(StringPtr theStr); - virtual void SpecialColorControl(); virtual short Slot(); virtual void SetLocal(); diff --git a/src/game/CScoreKeeper.cpp b/src/game/CScoreKeeper.cpp index af564858..45660186 100644 --- a/src/game/CScoreKeeper.cpp +++ b/src/game/CScoreKeeper.cpp @@ -45,7 +45,7 @@ enum { // For personal pages: kTeamNames }; -void CScoreKeeper::IScoreKeeper(CAvaraGame *theGame) { +CScoreKeeper::CScoreKeeper(CAvaraGame *theGame) { itsGame = theGame; // resRefNum = 0; // appResRefNum = CurResFile(); @@ -53,16 +53,16 @@ void CScoreKeeper::IScoreKeeper(CAvaraGame *theGame) { iface.command = 0; iface.result = 0; iface.capabilities = 0; - iface.plugIn = NULL; + // iface.plugIn = NULL; iface.maxPlayers = kMaxAvaraPlayers; iface.maxTeams = kMaxTeamColors; iface.frameTime = itsGame->frameTime; iface.frameNumber = -1; - iface.resultsHandle = NULL; //GetResource('TEXT', 300); + // iface.resultsHandle = NULL; //GetResource('TEXT', 300); // DetachResource(iface.resultsHandle); - iface.resultsChanged = false; + // iface.resultsChanged = false; // iface.resultsWindow = ((CAvaraApp *)gApplication)->theRosterWind->itsWindow; // SetRect(&iface.resultsRect, 0,0, 0,0); // iface.theEvent = NULL; @@ -95,11 +95,9 @@ void CScoreKeeper::IScoreKeeper(CAvaraGame *theGame) { playerRatings = std::make_unique(); } -void CScoreKeeper::Dispose() { - DisposeHandle(iface.resultsHandle); - iface.resultsHandle = NULL; - - CDirectObject::Dispose(); +CScoreKeeper::~CScoreKeeper() { + //DisposeHandle(iface.resultsHandle); + //iface.resultsHandle = NULL; } void CScoreKeeper::EndScript() { diff --git a/src/game/CScoreKeeper.h b/src/game/CScoreKeeper.h index 31c08159..ca68d106 100644 --- a/src/game/CScoreKeeper.h +++ b/src/game/CScoreKeeper.h @@ -10,7 +10,6 @@ #pragma once #include "AvaraDefines.h" #include "AvaraScoreInterface.h" -#include "CDirectObject.h" #include "PlayerRatingsSimpleElo.h" #define PLAYER_SCORE_FIELD_COUNT 6 @@ -42,7 +41,7 @@ struct FinishRecord { }; -class CScoreKeeper : public CDirectObject { +class CScoreKeeper { public: CAvaraGame *itsGame; ScoreInterfaceRecord iface; @@ -61,12 +60,8 @@ class CScoreKeeper : public CDirectObject { // player ratings stuff std::unique_ptr playerRatings; - virtual void IScoreKeeper(CAvaraGame *theGame); - virtual void Dispose(); - - // virtual OSErr OpenPlugIn(FSSpec *theFile); - // virtual void ClosePlugIn(); - // virtual void CallPlugIn(); + CScoreKeeper(CAvaraGame *theGame); + virtual ~CScoreKeeper(); virtual void EndScript(); virtual void StartResume(Boolean didStart); @@ -77,13 +72,6 @@ class CScoreKeeper : public CDirectObject { virtual void PlayerLeft(); virtual void PlayerJoined(); - - /* - virtual void Click(EventRecord *theEvent, Rect *theRect); - virtual Handle GetCustomText(); - virtual void DrawCustomWindow(Rect *theRect); - virtual void HideShow(Boolean doHide); - */ virtual void Score(ScoreInterfaceReasons reason, short team, short player, @@ -94,11 +82,6 @@ class CScoreKeeper : public CDirectObject { virtual void ResetScores(); virtual void ReceiveResults(int32_t *newResults); - // virtual void DrawOnePlayerResults(short slot, Rect *toRect); - // virtual void DrawResultsSummary(Rect *toRect); - // virtual void RegularClick(EventRecord *theEvent, Rect *theRect); - - // virtual void FilterConsoleLine(StringPtr theString, short align); std::vector DetermineFinishOrder(); void UpdatePlayerRatings(std::vector); diff --git a/src/game/CSmart.cpp b/src/game/CSmart.cpp index 6e5bdebd..e7e157b1 100644 --- a/src/game/CSmart.cpp +++ b/src/game/CSmart.cpp @@ -248,9 +248,9 @@ void CSmart::TurnTowardsTarget() { RayTestWithGround(&rayHit, kSolidBit); if (rayHit.closestHit && rayHit.closestHit->theOwner == targetActor) { - toTarget[0] -= speed[0] << 1; - toTarget[1] -= speed[1] << 1; - toTarget[2] -= speed[2] << 1; + toTarget[0] -= speed[0] * 2; + toTarget[1] -= speed[1] * 2; + toTarget[2] -= speed[2] * 2; FindSpaceAngle(toTarget, &goodYaw, &goodPitch); diff --git a/src/hsnd2wav.cpp b/src/hsnd2wav.cpp deleted file mode 100644 index 2ac0f5c9..00000000 --- a/src/hsnd2wav.cpp +++ /dev/null @@ -1,319 +0,0 @@ -#define USE_LEGACY_HSND -#include "AudioFile.h" -#include "CHuffProcessor.h" -#include "FastMat.h" -#include "SDL2/SDL.h" -#include "SoundSystemDefines.h" -#include "BasePath.h" - -#include - -typedef struct { - uint32_t versNum; - uint32_t loopStart; - uint32_t loopEnd; - uint32_t loopCount; - uint32_t dataOffset; - UnsignedFixed baseRate; -} LegacyHSNDRecord; - -struct SampleHeader { - int16_t resId; - int16_t refCount; - uint32_t len; - uint32_t loopStart; - uint32_t loopEnd; - uint32_t loopCount; - UnsignedFixed baseRate; - struct SampleHeader **nextSample; - int16_t flags; -}; - -enum { kOldSampleFlag = 1 }; - -typedef struct SampleHeader SampleHeader; -typedef SampleHeader *SampleHeaderPtr; -typedef SampleHeaderPtr *SampleHeaderHandle; - -static SampleHeaderHandle sampleList = NULL; -static CHuffProcessor *itsCompressor = new CHuffProcessor; - -static std::string defaultResource(GetBasePath() + "rsrc/Avara.r"); - -static std::string currentResource(""); - -bool IsEquals(const std::string& str1, const std::string& str2) { - return str1.length() == str2.length() && - std::equal(str1.begin(), str1.end(), str2.begin(), - [](char a, char b) { - return tolower(a) == tolower(b); - }); -} - -void UseResFile(std::string filename) { - currentResource.assign(GetBasePath() + filename); -} - -Handle FindResource(SDL_RWops *file, OSType theType, short theID, std::string name) { - uint32_t dataOffset = SDL_ReadBE32(file); - uint32_t mapOffset = SDL_ReadBE32(file); - // uint32_t dataLen = - SDL_ReadBE32(file); - // uint32_t mapLen = - SDL_ReadBE32(file); - - SDL_RWseek(file, mapOffset + 22, 0); - - //uint16_t forkAttrs = - SDL_ReadBE16(file); - - uint16_t typeListOffset = SDL_ReadBE16(file); - uint16_t nameListOffset = SDL_ReadBE16(file); - int16_t numTypes = SDL_ReadBE16(file); - - uint32_t offset = mapOffset + typeListOffset + 2; - while (numTypes >= 0) { - SDL_RWseek(file, offset, 0); // already read num_types above - - uint32_t rsrcType = SDL_ReadBE32(file); - int16_t numResources = SDL_ReadBE16(file); - uint16_t rsrcListOffset = SDL_ReadBE16(file); - - uint32_t rsrcOffset = mapOffset + typeListOffset + rsrcListOffset; - while (numResources >= 0) { - SDL_RWseek(file, rsrcOffset, 0); - - uint16_t rsrcId = SDL_ReadBE16(file); - int16_t nameOffset = SDL_ReadBE16(file); - uint32_t rsrcInfo = SDL_ReadBE32(file); - uint32_t rsrcDataOffset = dataOffset + (rsrcInfo & 0x00FFFFFF); - std::string rsrcName; - - bool nameMatch = false; - if (nameOffset >= 0 && name != "") { - // Only read the resource name if we're looking up by name. - uint32_t rsrcNameOffset = mapOffset + nameListOffset + nameOffset; - SDL_RWseek(file, rsrcNameOffset, 0); - const uint8_t nameLen = SDL_ReadU8(file); - char* cName = new char[nameLen]; - SDL_RWread(file, cName, nameLen, 1); - std::string rsrcName(cName, nameLen); - nameMatch = IsEquals(rsrcName, name); - delete[] cName; - } - - if (rsrcType == theType && ((rsrcId == theID) || nameMatch)) { - SDL_RWseek(file, rsrcDataOffset, 0); - uint32_t rsrcDataLen = SDL_ReadBE32(file); - Handle h = NewHandle(rsrcDataLen); - SDL_RWread(file, *h, rsrcDataLen, 1); - return h; - } - - rsrcOffset += 12; - numResources--; - } - - offset += 8; - numTypes--; - } - - return NULL; -} - -Handle _GetResource(OSType theType, short theID, std::string theName) { - /* - // TODO: handle TEXT, BSPT (bsp templates) - // everything else is just checking if it's there and not using the data - std::string typeString = OSTypeString(theType); - std::string idString = std::to_string(theID); - - nlohmann::json result = GetKeyFromSetJSON(typeString, idString, 0); - if (result == -1) return NULL; - else return NewHandle(0); - */ - SDL_RWops *file; - Handle data = NULL; - - // If there is a "current" resource file, look there first. - if (currentResource.size() > 0) { - //SDL_Log("Loading %i : %s from %s", theID, theName.c_str(), currentResource.c_str()); - if ((file = SDL_RWFromFile(currentResource.c_str(), "rb"))) { - data = FindResource(file, theType, theID, theName); - SDL_RWclose(file); - } - } - - // If there is no current resource file, or the resource wasn't found there, look in the default file. - if (data == NULL) { - //SDL_Log("Loading %i : %s from Avara resource", theID, theName.c_str()); - if ((file = SDL_RWFromFile(defaultResource.c_str(), "rb"))) { - data = FindResource(file, theType, theID, theName); - SDL_RWclose(file); - } - } - - return data; - -} - -Handle GetResource(OSType theType, short theID) { - return _GetResource(theType, theID, ""); -} - -void ReleaseResource(Handle theResource) { - DisposeHandle(theResource); -} - -SampleHeaderHandle LoadSampleLegacy(short resId) { - SampleHeaderHandle aSample; - SampleHeaderPtr sampP; - - aSample = sampleList; - - while (aSample) { - sampP = *aSample; - if (sampP->resId == resId) { - sampP->flags = 0; - break; - } - aSample = sampP->nextSample; - } - - if (!aSample) { - Handle compressedData; - - compressedData = GetResource(HSOUNDRESTYPE, resId); - if (compressedData) { - int len; - //short tryCount; - Ptr soundData; - //float base; - LegacyHSNDRecord *ir; - - // MoveHHi(compressedData); - HLock(compressedData); - - ir = (LegacyHSNDRecord *)*compressedData; - - ir->versNum = ntohl(ir->versNum); - ir->loopStart = ntohl(ir->loopStart); - ir->loopEnd = ntohl(ir->loopEnd); - ir->loopCount = ntohl(ir->loopCount); - ir->dataOffset = ntohl(ir->dataOffset); - if (ir->versNum >= 2) { - ir->baseRate = ntohl(ir->baseRate); - //base = ir->baseRate / 65536.0; - } - //else { - // base = 1.0; - //} - - soundData = ir->dataOffset + *compressedData; - len = itsCompressor->GetUncompressedLen(soundData); - - //SDL_Log("LegacyHSNDRecord versNum=%d, loopStart=%d, loopEnd=%d, loopCount=%d, dataOffset=%d, baseRate=%f, len=%i\n", - //ir->versNum, ir->loopStart, ir->loopEnd, ir->loopCount, ir->dataOffset, base, len); - - aSample = (SampleHeaderHandle)NewHandle(sizeof(SampleHeader) + len); - - if (aSample) { - uint8_t value; - uint8_t *p; - size_t i; - - sampP = *aSample; - sampP->resId = resId; - sampP->refCount = 0; - sampP->flags = 0; - sampP->len = len; - sampP->loopStart = ir->loopStart; - sampP->loopEnd = ir->loopEnd; - sampP->loopCount = ir->loopCount; - sampP->nextSample = sampleList; - - if (ir->versNum < 2) { - sampP->baseRate = FIX1; - } else { - sampP->baseRate = ir->baseRate; - } - - sampleList = aSample; - - HLock((Handle)aSample); - p = sizeof(SampleHeader) + (unsigned char *)sampP; - itsCompressor->Uncompress(soundData, (Ptr)p); - HUnlock((Handle)aSample); - - value = 128 >> (8 - BITSPERSAMPLE); - for (i = 0; i < len; i++) { - value += *p; - *p++ = value & (0xFF >> (8 - BITSPERSAMPLE)); - } - } - - ReleaseResource(compressedData); - } - } - - return aSample; -} - -void DisposeSamples() { - SampleHeaderHandle aSample, nextSample, *prevP; - - prevP = &sampleList; - - aSample = sampleList; - while (aSample) { - nextSample = (*aSample)->nextSample; - GetHandleSize((Handle)aSample); - DisposeHandle((Handle)aSample); - *prevP = nextSample; - aSample = nextSample; - } -} - -int main(int argc, char *argv[]) { - if (argc < 3) { - printf("Usage: hsnd2wav [hsnd_num] [outfile] [rsrc]\n"); - return 1; - } - - if (argc > 3) { - SDL_Log("UseResFile: %s", argv[3]); - UseResFile(argv[3]); - } - - char *file_name = argv[2]; - - InitMatrix(); - itsCompressor->Open(); - - int resId = std::stoi(argv[1]); - SampleHeaderHandle header = LoadSampleLegacy(resId); - - if (header) { - SampleHeaderPtr sp = *header; - int len = sp->len; - unsigned char *p = sizeof(SampleHeader) + (unsigned char *)sp; - - AudioFile audioFile; - audioFile.setSampleRate(ToFloat(sp->baseRate) * 22254.54545); - audioFile.setAudioBufferSize(1, len); // 1 channel, num samples - for (int i = 0; i < len; i++) { - // Avara samples were 7-bit (0-127), introduce some range for The Tools. - audioFile.samples[0][i] = p[i] * 2; - } - SDL_Log("Saving %s", file_name); - audioFile.printSummary(); - audioFile.save(file_name); - } else { - SDL_Log("HSND resource not found"); - } - - itsCompressor->Dispose(); - DisposeSamples(); - - return 0; -} diff --git a/src/level/Parser.cpp b/src/level/Parser.cpp index 122b851a..5322d70b 100644 --- a/src/level/Parser.cpp +++ b/src/level/Parser.cpp @@ -1106,10 +1106,11 @@ const std::optional ReadColorVar(const char *s) { return ReadColorVar(IndexForEntry(s)); } -const Fixed ReadFixedMaterialVar(short index) { +Fixed ReadFixedMaterialVar(short index) { return ToFixed(EvalVariable(index + firstVariable, true)); // eager evaluation! } -const Fixed ReadFixedMaterialVar(const char *s) { + +Fixed ReadFixedMaterialVar(const char *s) { return ReadFixedMaterialVar(IndexForEntry(s)); } diff --git a/src/level/Parser.h b/src/level/Parser.h index 8fa0ae92..a42a04a0 100644 --- a/src/level/Parser.h +++ b/src/level/Parser.h @@ -125,8 +125,8 @@ short ReadShortVar(short index); short ReadShortVar(const char *s); const std::optional ReadColorVar(short index); const std::optional ReadColorVar(const char *); -const Fixed ReadFixedMaterialVar(short index); -const Fixed ReadFixedMaterialVar(const char *s); +Fixed ReadFixedMaterialVar(short index); +Fixed ReadFixedMaterialVar(const char *s); std::string ReadStringVar(short index); std::string ReadStringVar(const char *); diff --git a/src/net/CCommManager.cpp b/src/net/CCommManager.cpp index 65caa623..d3a8dcbf 100644 --- a/src/net/CCommManager.cpp +++ b/src/net/CCommManager.cpp @@ -19,22 +19,17 @@ ** Initialize the packet buffer queues and allocate space ** for buffers. */ -void CCommManager::ICommManager(short packetSpace) { - // base class creates PacketInfo buffers/queues - InitializePacketQueues(packetSpace, sizeof(PacketInfo)); -} - -void CCommManager::InitializePacketQueues(int numPackets, std::size_t pSize) { +CCommManager::CCommManager(short packetSpace, size_t pSize) { packetSize = pSize; - myId = 0; // Default to server. + myId = 0; // Default to server. InitQueue(&freeQ); InitQueue(&inQ); - + firstReceivers[0] = NULL; firstReceivers[1] = NULL; - AllocatePacketBuffers(numPackets); + AllocatePacketBuffers(packetSpace); } void CCommManager::AllocatePacketBuffers(int numPackets) { @@ -49,12 +44,6 @@ void CCommManager::AllocatePacketBuffers(int numPackets) { } } -/* -** Release allocated packet buffer storage and then dispose of self. -*/ -void CCommManager::Dispose() { -} - /* ** Move parameters to a new packet buffer and use WriteAndSignPacket method to ** send the packet. diff --git a/src/net/CCommManager.h b/src/net/CCommManager.h index feb5421c..c8fa1fb5 100644 --- a/src/net/CCommManager.h +++ b/src/net/CCommManager.h @@ -8,7 +8,6 @@ */ #pragma once -#include "CDirectObject.h" #include "Memory.h" #include #include @@ -53,7 +52,7 @@ typedef struct ReceiverRecord ReceiverRecord; ** functionality. */ -class CCommManager : public CDirectObject { +class CCommManager { public: short myId; // Required/accessed publicly @@ -69,18 +68,19 @@ class CCommManager : public CDirectObject { RolloverCounter totalPacketsSent = 0; // For method documentation, see .c-file: - ~CCommManager() { Dispose(); } - virtual void ICommManager(short packetSpace); + CCommManager() : CCommManager(MINIMUMBUFFERRESERVE, sizeof(PacketInfo)) {} + CCommManager(short packetSpace, size_t pSize); + virtual ~CCommManager() {} + + virtual void Finalize() {} - void InitializePacketQueues(int numPackets, size_t packetSize); void AllocatePacketBuffers(int numPackets); virtual void AddReceiver(ReceiverRecord *aReceiver, Boolean delayed); virtual void RemoveReceiver(ReceiverRecord *aReceiver, Boolean delayed); virtual OSErr SendPacket(short distribution, int8_t command, int8_t p1, int16_t p2, int32_t p3, int16_t dataLen, Ptr dataPtr, int16_t flags = 0); virtual OSErr SendUrgentPacket(short distribution, int8_t command, int8_t p1, int16_t p2, int32_t p3, int16_t dataLen, Ptr dataPtr); - virtual void Dispose(); virtual PacketInfo *GetPacket(); virtual PacketInfo *DuplicatePacket(PacketInfo *original); diff --git a/src/net/CProtoControl.cpp b/src/net/CProtoControl.cpp index 0cda6232..cd43178c 100644 --- a/src/net/CProtoControl.cpp +++ b/src/net/CProtoControl.cpp @@ -40,7 +40,7 @@ static Boolean DelayedProtoHandler(PacketInfo *thePacket, Ptr userData) { return theControl->DelayedPacketHandler(thePacket); } -void CProtoControl::IProtoControl(CCommManager *aManager, CAvaraGame *aGame) { +CProtoControl::CProtoControl(CCommManager *aManager, CAvaraGame *aGame) { theGame = aGame; immedReceiverRecord.handler = ImmedProtoHandler; @@ -264,7 +264,3 @@ void CProtoControl::Detach() { itsManager = NULL; } } - -void CProtoControl::Dispose() { - CDirectObject::Dispose(); -} diff --git a/src/net/CProtoControl.h b/src/net/CProtoControl.h index b2c2a6a5..14a60833 100644 --- a/src/net/CProtoControl.h +++ b/src/net/CProtoControl.h @@ -9,19 +9,19 @@ #pragma once #include "CCommManager.h" -#include "CDirectObject.h" -class CProtoControl : public CDirectObject { +class CProtoControl { public: CCommManager *itsManager; class CAvaraGame *theGame; ReceiverRecord immedReceiverRecord; ReceiverRecord delayedReceiverRecord; - virtual void IProtoControl(CCommManager *aManager, CAvaraGame *aGame); + CProtoControl(CCommManager *aManager, CAvaraGame *aGame); + virtual ~CProtoControl() {} + virtual Boolean PacketHandler(PacketInfo *thePacket); virtual Boolean DelayedPacketHandler(PacketInfo *thePacket); - virtual void Dispose(); virtual void Attach(CCommManager *aManager); virtual void Detach(); diff --git a/src/net/CUDPComm.cpp b/src/net/CUDPComm.cpp index 4ab7069e..2b46257f 100755 --- a/src/net/CUDPComm.cpp +++ b/src/net/CUDPComm.cpp @@ -1257,10 +1257,8 @@ ClockTick CUDPComm::GetClock() { ** more urgent data. If not, any data marked urgent will be resent even if there ** no other data to send within twice that period. */ -void CUDPComm::IUDPComm(short clientCount, short bufferCount, uint16_t version, ClockTick urgentTimePeriod) { - // create queues big enough to hold UDPPacketInfo packets - InitializePacketQueues(bufferCount, sizeof(UDPPacketInfo)); - +CUDPComm::CUDPComm(short clientCount, short bufferCount, uint16_t version, ClockTick urgentTimePeriod) : CCommManager(bufferCount, sizeof(UDPPacketInfo)) +{ inviteString[0] = 0; softwareVersion = version; @@ -1273,11 +1271,6 @@ void CUDPComm::IUDPComm(short clientCount, short bufferCount, uint16_t version, // latencyConvert = urgentTimePeriod * 2; // no longer being used - /* - prefs = new CTagBase; - prefs->ITagBase(); - prefs->ConvertFromHandle(gApplication->prefsBase->ReadHandle(kUDPCommPrefsTag)); - */ retransmitToRoundTripRatio = 192 + (gApplication->Number(kUDPResendPrefTag) << 5); isConnected = false; @@ -1295,22 +1288,13 @@ void CUDPComm::IUDPComm(short clientCount, short bufferCount, uint16_t version, maxClients = clientCount; while (clientCount--) { - CUDPConnection *newConn; - - newConn = new CUDPConnection; - newConn->IUDPConnection(this); + CUDPConnection *newConn = new CUDPConnection(this); newConn->next = connections; connections = newConn; } nextSender = connections; - /* - writeComplete = NewUDPIOCompletionProc(UDPWriteComplete); - readComplete = NewUDPIOCompletionProc(UDPReadComplete); - bufferReturnComplete = NewUDPIOCompletionProc(UDPBufferReturnComplete); - */ - receiverRecord.handler = ImmedProtoHandler; receiverRecord.userData = (Ptr)this; AddReceiver(&receiverRecord, kUDPProtoHandlerIsAsync); @@ -1341,6 +1325,32 @@ void CUDPComm::IUDPComm(short clientCount, short bufferCount, uint16_t version, password[0] = 0; } +CUDPComm::~CUDPComm() { + CUDPConnection *nextConn; + + Finalize(); + + while (connections) { + nextConn = connections->next; + + delete connections; + connections = nextConn; + } +} + +void CUDPComm::Finalize() { + if (isConnected && !isClosed) { + if (myId == 0) + SendPacket(kdEveryone, kpPacketProtocolLogout, 0, 0, 0, 0, 0); + else + SendPacket(kdServerOnly, kpPacketProtocolLogout, myId, 0, 0, 0, 0); + + Disconnect(); + } + + RemoveReceiver(&receiverRecord, kUDPProtoHandlerIsAsync); +} + void CUDPComm::Disconnect() { long startTicks; long delta; @@ -1383,30 +1393,6 @@ void CUDPComm::Disconnect() { isClosed = true; } -void CUDPComm::Dispose() { - CUDPConnection *nextConn; - - if (isConnected && !isClosed) { - if (myId == 0) - SendPacket(kdEveryone, kpPacketProtocolLogout, 0, 0, 0, 0, 0); - else - SendPacket(kdServerOnly, kpPacketProtocolLogout, myId, 0, 0, 0, 0); - - Disconnect(); - } - - RemoveReceiver(&receiverRecord, kUDPProtoHandlerIsAsync); - - while (connections) { - nextConn = connections->next; - - connections->Dispose(); - connections = nextConn; - } - - CCommManager::Dispose(); -} - void CUDPComm::CreateServer() { localPort = gApplication->Number(kDefaultUDPPort); diff --git a/src/net/CUDPComm.h b/src/net/CUDPComm.h index 669493c8..d4db562d 100644 --- a/src/net/CUDPComm.h +++ b/src/net/CUDPComm.h @@ -44,12 +44,8 @@ class CUDPComm : public CCommManager { // OSErr writeErr; // OSErr readErr; - // class CTagBase *prefs; class CUDPConnection *connections; class CUDPConnection *nextSender; - /* - class CTracker *tracker; - */ long retransmitToRoundTripRatio; // In fixed point 24.8 format @@ -62,8 +58,6 @@ class CUDPComm : public CCommManager { ip_addr localIP; // Just a guess, but that's all we need for the tracker. port_num localPort; int stream; - // char streamBuffer[UDPSTREAMBUFFERSIZE]; - // char sendBuffer[UDPSENDBUFFERSIZE]; short cramData; @@ -76,17 +70,14 @@ class CUDPComm : public CCommManager { Boolean turboMode; long turboCount; - // Boolean readIsComplete; - // Boolean writeIsComplete; - // Boolean blockReadComplete; - // Boolean blockWriteComplete; Boolean specialWakeup; Str255 inviteString; - virtual void IUDPComm(short clientCount, short bufferCount, uint16_t version, ClockTick urgentTimePeriod); + CUDPComm(short clientCount, short bufferCount, uint16_t version, ClockTick urgentTimePeriod); + virtual ~CUDPComm(); + virtual void Finalize(); virtual void Disconnect(); - virtual void Dispose(); ClockTick GetClock(); diff --git a/src/net/CUDPConnection.cpp b/src/net/CUDPConnection.cpp index 742ee36d..efdc6ddf 100644 --- a/src/net/CUDPConnection.cpp +++ b/src/net/CUDPConnection.cpp @@ -56,7 +56,7 @@ void CUDPConnection::DebugPacket(char eType, UDPPacketInfo *p) { } #endif -void CUDPConnection::IUDPConnection(CUDPComm *theOwner) { +CUDPConnection::CUDPConnection(CUDPComm *theOwner) { short i; killed = false; @@ -111,6 +111,11 @@ void CUDPConnection::IUDPConnection(CUDPComm *theOwner) { recentResendRate = 0; } +CUDPConnection::~CUDPConnection() { + FlushQueues(); + delete latencyHistogram; +} + void CUDPConnection::FlushQueues() { QElemPtr elem; QHdr *head; @@ -586,12 +591,6 @@ void CUDPConnection::ResendNonValidatedPackets() { } } -void CUDPConnection::Dispose() { - FlushQueues(); - delete latencyHistogram; - CDirectObject::Dispose(); -} - static short receiveSerialStorage[512]; size_t CUDPConnection::ReceivedPacket(UDPPacketInfo *thePacket) { diff --git a/src/net/CUDPConnection.h b/src/net/CUDPConnection.h index 8f3abad6..ca60dc98 100644 --- a/src/net/CUDPConnection.h +++ b/src/net/CUDPConnection.h @@ -9,7 +9,6 @@ #pragma once #include "CCommManager.h" -#include "CDirectObject.h" #include "CommDefs.h" #include "RolloverCounter.h" #include "SlidingHistogram.h" @@ -57,7 +56,7 @@ typedef struct { enum { kReceiveQ, kTransmitQ, kBusyQ, kQueueCount }; -class CUDPConnection : public CDirectObject { +class CUDPConnection { public: class CUDPConnection *next; class CUDPComm *itsOwner; @@ -113,7 +112,9 @@ class CUDPConnection : public CDirectObject { Boolean killed; - virtual void IUDPConnection(CUDPComm *theMaster); + CUDPConnection(CUDPComm *theMaster); + virtual ~CUDPConnection(); + virtual void SendQueuePacket(UDPPacketInfo *thePacket, short theDistribution); virtual void RoutePacket(UDPPacketInfo *thePacket); virtual UDPPacketInfo *GetOutPacket(int32_t curTime, int32_t cramTime, int32_t urgencyAdjust); @@ -132,7 +133,6 @@ class CUDPConnection : public CDirectObject { virtual bool ReceiveQueuedPackets(); virtual void FlushQueues(); - virtual void Dispose(); virtual void MarkOpenConnections(CompleteAddress *table); virtual void RewriteConnections(CompleteAddress *table, const CompleteAddress &myAddressInTOC); diff --git a/src/tests.cpp b/src/tests.cpp index cedde7fa..cee147ef 100644 --- a/src/tests.cpp +++ b/src/tests.cpp @@ -31,6 +31,8 @@ using namespace std; class TestSoundHub : public CSoundHubImpl { public: + TestSoundHub(short numOfEachKind, short initialLinks) : CSoundHubImpl(numOfEachKind, + initialLinks) {} virtual Fixed* EarLocation() { return ear; } virtual bool AudioEnabled() { return false; } private: @@ -132,6 +134,8 @@ class TestPlayerManager : public CPlayerManager { class TestNetManager : public CNetManager { public: + TestNetManager(CAvaraGame *theGame) : CNetManager(theGame) {} + std::shared_ptr CreatePlayerManager(short id) { return std::make_shared(itsGame); } @@ -188,8 +192,8 @@ class TestApp : public CAvaraApp { class TestGame : public CAvaraGame { public: TestGame(int frameTime) : CAvaraGame(frameTime) {} - virtual std::unique_ptr CreateNetManager() { return std::make_unique(); } - virtual CSoundHub* CreateSoundHub() { TestSoundHub *t = new TestSoundHub(); t->ISoundHub(64,64); return t;} + virtual std::unique_ptr CreateNetManager() { return std::make_unique(this); } + virtual CSoundHub* CreateSoundHub() { return new TestSoundHub(64,64); } bool GameTick() { // force tick to happen by resetting nextScheduledFrame nextScheduledFrame = 0; @@ -1169,11 +1173,13 @@ TEST(SERIAL_NUMBER, Rollover) { UDPPacketInfo packet1, packet2; test_rollover("UDPPacketInfo::serialNumber", packet1, packet2, &UDPPacketInfo::serialNumber); - CUDPConnection conn1, conn2; + /* TODO: CUDPConnection relies on having gCurrentGame set up + CUDPConnection conn1(nullptr), conn2(nullptr); test_rollover("CUDPConnection::serialNumber", conn1, conn2, &CUDPConnection::serialNumber); test_rollover("CUDPConnection::receiveSerial", conn1, conn2, &CUDPConnection::receiveSerial); test_rollover("CUDPConnection::maxValid", conn1, conn2, &CUDPConnection::maxValid); test_rollover("CUDPConnection::ackBase", conn1, conn2, &CUDPConnection::ackBase); + */ } TEST(MATERIALS, Manipulation) { diff --git a/src/tui/TextCommand.cpp b/src/tui/TextCommand.cpp index def3def2..4b7cce01 100644 --- a/src/tui/TextCommand.cpp +++ b/src/tui/TextCommand.cpp @@ -67,7 +67,7 @@ bool TextCommand::FindMatchingCommands(std::string& fullText, return success; } -const bool TextCommand::ExecuteMatchingCallbacks(std::string& fullCommand) { +bool TextCommand::ExecuteMatchingCallbacks(std::string& fullCommand) { return FindMatchingCommands(fullCommand, [](TextCommand* command, std::string& cmd, VectorOfArgs vargs) -> bool { diff --git a/src/tui/TextCommand.h b/src/tui/TextCommand.h index e707c7cb..94874b73 100644 --- a/src/tui/TextCommand.h +++ b/src/tui/TextCommand.h @@ -38,7 +38,7 @@ class TextCommand { static void Register(TextCommand* command); static bool FindMatchingCommands(std::string& fullCommand, std::function matchCb); - static const bool ExecuteMatchingCallbacks(std::string& fullCommand); + static bool ExecuteMatchingCallbacks(std::string& fullCommand); static const std::string ListOfCommands(std::string delimeter = ", "); static std::string UsageForCommand(std::string& fullCommand); diff --git a/src/util/huffman/CAbstractHuffPipe.cpp b/src/util/huffman/CAbstractHuffPipe.cpp deleted file mode 100644 index 8e028e59..00000000 --- a/src/util/huffman/CAbstractHuffPipe.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include "CAbstractHuffPipe.h" - -/** - Initialize counters for each symbol (ASCII chars). - Initialize data counter to 0. - */ -OSErr CAbstractHuffPipe::Open() { - short i; - for (i = 0; i < NUMSYMBOLS; i++) { - symbCounters[i] = 1; - } - dataCount = 0; - return CAbstractPipe::Open(); -} - -/** - Shell sorts the first NUMSYMBOLS nodes. - */ -void CAbstractHuffPipe::SortNodes(HuffTreeNode **table) { - short h; - HuffTreeNode **ip, **jp, *vp; - HuffTreeNode **lastP; - HuffTreeNode **hp; - - h = 1; - lastP = table + NUMSYMBOLS; - - do { - h += h + h + 1; - } while (h <= NUMSYMBOLS); - - do { - h /= 3; - hp = table + h; - for (ip = hp; ip < lastP; ip++) { - vp = *ip; - jp = ip; - while (jp[-h]->count > vp->count) { - *jp = jp[-h]; - jp -= h; - if (jp < hp) { - break; - } - } - *jp = vp; - } - } while (h != 1); -} - -/** - Builds a Huffman tree using the given symbol distribution. - The root node of the tree is returned. - */ -HuffTreeNode *CAbstractHuffPipe::BuildTree() { - HuffTreeNode *subTrees[NUMSYMBOLS + 1]; - HuffTreeNode **treeList; - HuffTreeNode *freshNode; - HuffTreeNode markerNode; - short i; - - // Place symbols into the first NUMSYMBOLS places in the tree array. - for (i = 0; i < NUMSYMBOLS; i++) { - nodes[i].count = symbCounters[i]; - nodes[i].left = -1; - nodes[i].right = i; - } - - // Put pointers to the tree array into the subTrees array. - for (i = 0; i < NUMSYMBOLS; i++) { - subTrees[i] = &(nodes[i]); - } - - // Sort pointers in the subTree array so that the symbol with the lowest count is first, etc. - SortNodes(subTrees); - - // freshNode points to a free tree node: - freshNode = &(nodes[NUMSYMBOLS]); - - // Pointer to current list of subtrees: - treeList = subTrees; - - // Create a marker node to stop insertion sorts: - markerNode.count = dataCount + NUMSYMBOLS + 1; - subTrees[NUMSYMBOLS] = &markerNode; - - i = 1; - while ((*treeList)->count == 0) { - i++; - treeList++; - } - - // Reduce tree into a root node. Requires NUMSYMBOLS-1 steps: - for (; i < NUMSYMBOLS; i++) { - HuffTreeNode *aNode, *bNode; - HuffTreeNode **sorter; - int count; - - // Combine the two subtrees with the lowest counts: - aNode = treeList[0]; - bNode = treeList[1]; - treeList++; - - count = aNode->count + bNode->count; - - freshNode->count = count; - freshNode->left = aNode - nodes; - freshNode->right = bNode - nodes; - - // Sort the new subtree into the list of subtrees: - sorter = treeList + 1; - - // >= is used to keep order in the equal distribution case. > could be used as well. - while (count >= (*sorter)->count) { - sorter[-1] = sorter[0]; - sorter++; - } - - sorter[-1] = freshNode; - - freshNode++; - } - - return treeList[0]; -} - -/** - This abstract class doesn't pass any data forward. This method was used to test the tree - creation code. - */ -OSErr CAbstractHuffPipe::PipeData(Ptr dataPtr, long len) { - dataCount += len; - while (len--) { - symbCounters[*(unsigned char *)(dataPtr++)]++; - } - return noErr; -} diff --git a/src/util/huffman/CAbstractHuffPipe.h b/src/util/huffman/CAbstractHuffPipe.h deleted file mode 100644 index 8fd30091..00000000 --- a/src/util/huffman/CAbstractHuffPipe.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include "CAbstractPipe.h" - -// Number of symbols in the compressed data. Don't change this unless you know what you are doing. -#define NUMSYMBOLS 256 - -// Defines a condition for when the tree should change. -#define CHANGEOFPATTERNS (dataCount == 256 || (dataCount & 2047) == 0) - -typedef struct { - int count; - short left; // If negative, this is a leaf node and right is the value. - short right; -} HuffTreeNode; - -class CAbstractHuffPipe : public CAbstractPipe { -public: - int dataCount; - int symbCounters[NUMSYMBOLS]; - HuffTreeNode nodes[NUMSYMBOLS * 2 - 1]; - - CAbstractHuffPipe() {} - virtual ~CAbstractHuffPipe() {} - - virtual OSErr Open(); - virtual void SortNodes(HuffTreeNode **table); - virtual HuffTreeNode *BuildTree(); - virtual OSErr PipeData(Ptr dataPtr, long len); -}; diff --git a/src/util/huffman/CAbstractPipe.cpp b/src/util/huffman/CAbstractPipe.cpp deleted file mode 100644 index e9e774ac..00000000 --- a/src/util/huffman/CAbstractPipe.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "CAbstractPipe.h" - -/** - Open a null pipe that does nothing. Basically a /dev/null kind of device. - */ -OSErr CAbstractPipe::Open() { - outputStream = NULL; - return noErr; -} - -/** - Set the next pipe in chain. - */ -OSErr CAbstractPipe::PipeTo(CAbstractPipe *output) { - outputStream = output; - return noErr; -} - -/** - In essence, this is the Write command for a pipe. Whatever is written with this command is - processed and then output to the output pipe, if there is one or the use of one is allowed. - */ -OSErr CAbstractPipe::PipeData(Ptr dataPtr, long len) { - if (outputStream) { - return outputStream->PipeData(dataPtr, len); - } else { - return noErr; - } -} - -/** - Closes the pipe. Subclasses can flush any data they have buffered and then close their output - pipe. It's probably not a good idea to close the output pipe at this point, since the user might - want to use it for more data. Maybe a separate flush command and then a close could be in order? - */ -OSErr CAbstractPipe::Close() { - if (outputStream) { - return outputStream->Close(); - } else { - return noErr; - } -} diff --git a/src/util/huffman/CAbstractPipe.h b/src/util/huffman/CAbstractPipe.h deleted file mode 100644 index a4fe7832..00000000 --- a/src/util/huffman/CAbstractPipe.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "Types.h" - -class CAbstractPipe { -public: - class CAbstractPipe *outputStream; - - CAbstractPipe() {} - virtual ~CAbstractPipe() {} - - // In general, pipe methods are used in this order: - virtual OSErr Open(); - virtual OSErr PipeTo(CAbstractPipe *output); - virtual OSErr PipeData(Ptr dataPtr, long len); - virtual OSErr Close(); -}; diff --git a/src/util/huffman/CHuffProcessor.cpp b/src/util/huffman/CHuffProcessor.cpp deleted file mode 100644 index 13a4912e..00000000 --- a/src/util/huffman/CHuffProcessor.cpp +++ /dev/null @@ -1,381 +0,0 @@ -#include "CHuffProcessor.h" - -#ifndef INTEL_ARCH -#define MEM_LONG(val) val -#define MEM_SHORT(val) val -#else -#define MEM_LONG(val) ((val << 24) | ((val << 8) & 0xFF0000) | ((val >> 8) & 0xFF00) | ((val >> 24) & 0xFF)) -#define MEM_SHORT(val) (short)((val << 8) | ((val >> 8) & 0xFF)) -#endif - -/** - Decoding the data is a bit more complicated than writing it, since we have to walk the tree to - find what maps to what. We can, however, take a shortcut by reading HUFFHANDLELOOKUPBITS bits at - a time. If the code we reach is shorter than this, all we need to do is back up a few bits. If - we did not reach a leaf node with the lookup, we continue bit by bit until we reach a leaf. - - This routine creates the lookup table for HUFFHANDLELOOKUPBITS bits and it creates a table of - lengths so that we can find out how many bits were needed for the last char. - - Recursion has been eliminated with a stack and the routine is a modified version of the one used - to create the tables in the encoder object. - - The routine goes through the patterns in order starting with 000... and ending at 111... - Because of this, the "holes" in the lookup table can be filled as we go. The last pointer - written to the table has to be replicated until the end of the table. - - If BuildTree returns a leaf node, then the tree can only have one symbol in it and using huffman - compression doesn't make any sense (since the code consists of only one repeated symbol). - */ -void CHuffProcessor::CreateLookupBuffer() { - short lastLookup; - short walkerStack[33]; - short *stackPtr, *endPtr; - short codeLen = 1; - int codeString = 0; - HuffTreeNode *theNode; - HuffTreeNode *lastNode; - - theNode = BuildTree(); - - singleSymbolData = (theNode->left < 0); - theSingleSymbol = theNode->right; - - // Must be branch node. - if (!singleSymbolData) { - stackPtr = walkerStack + 1; - endPtr = walkerStack + 32; - *stackPtr++ = theNode->right; - theNode = &nodes[theNode->left]; - lastLookup = 0; - - do { - if (codeLen == HUFFHANDLELOOKUPBITS || (theNode->left < 0 && codeLen < HUFFHANDLELOOKUPBITS)) { - int codeIndex; - codeIndex = codeString << (HUFFHANDLELOOKUPBITS - codeLen); - lastNode = lookupBuf[lastLookup]; - while (lastLookup < codeIndex) { - lookupBuf[lastLookup++] = lastNode; - } - lookupBuf[codeIndex] = theNode; - } - - if (theNode->left < 0) { - codeLengths[theNode->right] = codeLen; - theNode = &nodes[*--stackPtr]; - while (codeString & 1) { - codeLen--; - codeString >>= 1; - }; - codeString |= 1; - } else { - *stackPtr++ = theNode->right; - theNode = &nodes[theNode->left]; - codeLen++; - codeString += codeString; - } - } while (stackPtr <= endPtr && stackPtr != walkerStack); - - lastNode = lookupBuf[lastLookup]; - while (lastLookup < HUFFHANDLELOOKUPSIZE) { - lookupBuf[lastLookup++] = lastNode; - } - } -} - -/** - Create a mapping from characters to bit patterns. Lengths are stored in a different array. Bit - patterns may be up to 24 bits int (the limitation comes from the output code). - - A stack is used to eliminate recursion while walking the tree. - - If BuildTree returns a leaf node, then the tree can only have one symbol in it and using huffman - compression doesn't make any sense (since the code consists of only one repeated symbol). - */ -void CHuffProcessor::CreateSymbolTable() { - short walkerStack[33]; - short *stackPtr; - short codeLen = 1; - int codeString = 0; - HuffTreeNode *theNode; - - theNode = BuildTree(); - - singleSymbolData = (theNode->left < 0); - - // Must be branch node. - if (!singleSymbolData) { - stackPtr = walkerStack + 1; - *stackPtr++ = theNode->right; - theNode = &nodes[theNode->left]; - - do { - if (theNode->left < 0) { - codeStrings[theNode->right] = codeString; - codeLengths[theNode->right] = codeLen; - theNode = &nodes[*--stackPtr]; - while (codeString & 1) { - codeLen--; - codeString >>= 1; - }; - codeString |= 1; - } else { - *stackPtr++ = theNode->right; - theNode = &nodes[theNode->left]; - codeLen++; - codeString += codeString; - } - } while (stackPtr != walkerStack); - } -} - -void CHuffProcessor::DecodeAll(unsigned char *source, unsigned char *dest) { - int i; - int bitData; - int *bitPointer; - int bitPosition = 0; - HuffTreeNode *theNode; - short theCode; - - i = dataCount; - while (i--) { - // Read in some bits into bitData. - bitPointer = (int *)(source + (bitPosition >> 3)); -#ifdef INTEL_ARCH - { - unsigned char *charPointer = (unsigned char *)bitPointer; - - bitData = (((unsigned int)charPointer[0] << 24) | ((unsigned int)charPointer[1] << 16) | - ((unsigned int)charPointer[2] << 8) | (unsigned int)charPointer[3]) - << (bitPosition & 7); - } -#else - bitData = (*bitPointer) << (bitPosition & 7); -#endif - - // Use the lookup table to see what these bits decode to: - theNode = lookupBuf[(bitData >> (32 - HUFFHANDLELOOKUPBITS)) & (HUFFHANDLELOOKUPSIZE - 1)]; - - // If we didn't reach a leaf node, proceed bit by bit. - if (theNode->left >= 0) { - int mask = 1L << (31 - HUFFHANDLELOOKUPBITS); - - // Decode one bit at a time and walk the tree. - do { - if (mask & bitData) { - theNode = nodes + theNode->right; - } else { - theNode = nodes + theNode->left; - } - mask >>= 1; - } while (theNode->left >= 0); - } - - // Move the decoded symbol to theCode - theCode = theNode->right; - *dest++ = theCode; - - // Mark n bits as read. - bitPosition += codeLengths[theCode]; - } -} - -int CHuffProcessor::GetUncompressedLen(Ptr compressedData) { - HuffDataHeader *inHeader; - inHeader = (HuffDataHeader *)compressedData; - dataCount = MEM_LONG(inHeader->decodedSize); - return dataCount; -} - -void CHuffProcessor::Uncompress(Ptr fromPtr, Ptr destPtr) { - HuffDataHeader *inHeader; - unsigned int *freqCounts; - unsigned short *freqCountsShort; - short i, j, k; - HuffTreeNode *lookupMem[HUFFHANDLELOOKUPSIZE]; - - lookupBuf = lookupMem; - inHeader = (HuffDataHeader *)fromPtr; - dataCount = MEM_LONG(inHeader->decodedSize); - outPointer = destPtr; - - if (destPtr && dataCount) { - freqCounts = (unsigned int *)(sizeof(HuffDataHeader) + fromPtr); - - k = 0; - - freqCountsShort = (unsigned short *)freqCounts; - - for (i = 0; i < (NUMSYMBOLS >> 5); i++) { - int flags; - flags = MEM_LONG(inHeader->countBitmap[i]); - - for (j = 0; j < 32; j++) { - if (dataCount > 65535) { - int temp = (flags < 0) ? *freqCounts++ : 0; - symbCounters[k++] = MEM_LONG(temp); - } else { - short temp = (flags < 0) ? *freqCountsShort++ : 0; - symbCounters[k++] = MEM_SHORT(temp); - } - flags += flags; - } - } - - if (dataCount <= 65535) { - freqCounts = (unsigned int *)freqCountsShort; - } - - CreateLookupBuffer(); - - if (singleSymbolData) { - Ptr p = destPtr; - while (dataCount--) { - *p++ = theSingleSymbol; - } - } else { - DecodeAll((unsigned char *)freqCounts, (unsigned char *)destPtr); - } - } -} - -int CHuffProcessor::GetCompressedLen(Ptr sourceData, int sourceLen) { - int outSize; - int outputBits = 0; - short countDataSize; - short nonZero = 0; - int i; - - dataCount = sourceLen; - - if (dataCount) { - unsigned char *p; - int *t; - t = symbCounters; - for (i = 0; i < NUMSYMBOLS; i++) { - t[i] = 0; - } - - i = sourceLen; - p = (unsigned char *)sourceData; - while (i--) { - (t[*p++])++; - } - - CreateSymbolTable(); - - if (singleSymbolData) { - outputBits = 0; - nonZero = 1; - } else { - // Count how many bits are needed for output. - for (i = 0; i < NUMSYMBOLS; i++) { - if (symbCounters[i]) { - nonZero++; - outputBits += symbCounters[i] * codeLengths[i]; - } - } - } - - countDataSize = dataCount > 65535 ? sizeof(int) : sizeof(short); - outCount = ((outputBits + 7) >> 3); - outSize = nonZero * countDataSize + // Stored counts - sizeof(HuffDataHeader) + // Header size - outCount; // Number of encoded bytes - } else { - outSize = sizeof(int); - outCount = 0; - } - - return outSize; -} - -void CHuffProcessor::Compress(Ptr fromPtr, Ptr destPtr) { - short i, j, k; - HuffDataHeader *outHeader; - - int count; - int *zeroL; - char *zeroC; - - zeroL = (int *)destPtr; - count = outCount >> 2; - while (count--) { - *zeroL++ = 0; - } - - zeroC = (char *)zeroL; - count = outCount & 3; - while (count--) { - *zeroC++ = 0; - } - - outHeader = (HuffDataHeader *)destPtr; - outHeader->decodedSize = MEM_LONG(dataCount); - - if (dataCount) { - unsigned char *inData, *endData; - int outBits; - int outLen; - int bitOffset; - unsigned int *countTable; - unsigned short *countTableShort; - - k = 0; - for (i = 0; i < (NUMSYMBOLS >> 5); i++) { - int flags = 0; - for (j = 0; j < 32; j++) { - flags += flags; - flags |= (symbCounters[k++] != 0); - } - outHeader->countBitmap[i] = MEM_LONG(flags); - } - - if (dataCount > 65535) { - countTable = (unsigned int *)(sizeof(HuffDataHeader) + destPtr); - for (i = 0; i < NUMSYMBOLS; i++) { - if (symbCounters[i]) { - *countTable++ = MEM_LONG(symbCounters[i]); - } - } - } else { - countTableShort = (unsigned short *)(sizeof(HuffDataHeader) + destPtr); - for (i = 0; i < NUMSYMBOLS; i++) { - if (symbCounters[i]) { - *countTableShort++ = MEM_SHORT(symbCounters[i]); - } - } - countTable = (unsigned int *)countTableShort; - } - - if (!singleSymbolData) { - bitOffset = 0; - inData = (unsigned char *)fromPtr; - endData = inData + dataCount; - - while (inData < endData) { - int *tempBitP; - - outBits = codeStrings[*inData]; - outLen = codeLengths[*inData++]; - - tempBitP = (int *)((char *)countTable + (bitOffset >> 3)); -#ifdef INTEL_ARCH - { - unsigned char *destP = (unsigned char *)tempBitP; - unsigned int orData; - - orData = outBits << (32 - ((bitOffset & 7) + outLen)); - *destP++ |= orData >> 24; - *destP++ |= orData >> 16; - *destP++ |= orData >> 8; - *destP |= orData; - } -#else - *tempBitP |= outBits << (32 - ((bitOffset & 7) + outLen)); -#endif - bitOffset += outLen; - } - } - } -} diff --git a/src/util/huffman/CHuffProcessor.h b/src/util/huffman/CHuffProcessor.h deleted file mode 100644 index 9346cb73..00000000 --- a/src/util/huffman/CHuffProcessor.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include "CAbstractHuffPipe.h" - -typedef struct { - uint32_t decodedSize; - uint32_t countBitmap[NUMSYMBOLS >> 5]; -} HuffDataHeader; - -#define HUFFHANDLELOOKUPBITS 10 -#define HUFFHANDLELOOKUPSIZE (1 << HUFFHANDLELOOKUPBITS) - -class CHuffProcessor : public CAbstractHuffPipe { -public: - Ptr outPointer; - int outCount; - - HuffTreeNode **lookupBuf; - Boolean singleSymbolData; - unsigned char theSingleSymbol; - int codeStrings[NUMSYMBOLS]; - short codeLengths[NUMSYMBOLS]; - - CHuffProcessor() {} - virtual ~CHuffProcessor() {} - - virtual void CreateLookupBuffer(); - virtual void CreateSymbolTable(); - virtual void DecodeAll(unsigned char *source, unsigned char *dest); - - virtual int GetUncompressedLen(Ptr compressedData); - virtual int GetCompressedLen(Ptr sourceData, int sourceLen); - - virtual void Compress(Ptr fromPtr, Ptr destPtr); - virtual void Uncompress(Ptr fromPtr, Ptr destPtr); -}; diff --git a/vendor/AudioFile.h b/vendor/AudioFile.h deleted file mode 100644 index 375f4b90..00000000 --- a/vendor/AudioFile.h +++ /dev/null @@ -1,1302 +0,0 @@ -//======================================================================= -/** @file AudioFile.h - * @author Adam Stark - * @copyright Copyright (C) 2017 Adam Stark - * - * This file is part of the 'AudioFile' library - * - * 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 3 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, see . - */ -//======================================================================= - -#ifndef _AS_AudioFile_h -#define _AS_AudioFile_h - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// disable some warnings on Windows -#if defined (_MSC_VER) - __pragma(warning (push)) - __pragma(warning (disable : 4244)) - __pragma(warning (disable : 4457)) - __pragma(warning (disable : 4458)) - __pragma(warning (disable : 4389)) - __pragma(warning (disable : 4996)) -#elif defined (__GNUC__) - _Pragma("GCC diagnostic push") - _Pragma("GCC diagnostic ignored \"-Wconversion\"") - _Pragma("GCC diagnostic ignored \"-Wsign-compare\"") - _Pragma("GCC diagnostic ignored \"-Wshadow\"") -#endif - -//============================================================= -/** The different types of audio file, plus some other types to - * indicate a failure to load a file, or that one hasn't been - * loaded yet - */ -enum class AudioFileFormat -{ - Error, - NotLoaded, - Wave, - Aiff -}; - -//============================================================= -template -class AudioFile -{ -public: - - //============================================================= - typedef std::vector > AudioBuffer; - - //============================================================= - /** Constructor */ - AudioFile(); - - /** Constructor, using a given file path to load a file */ - AudioFile (std::string filePath); - - //============================================================= - /** Loads an audio file from a given file path. - * @Returns true if the file was successfully loaded - */ - bool load (std::string filePath); - - /** Saves an audio file to a given file path. - * @Returns true if the file was successfully saved - */ - bool save (std::string filePath, AudioFileFormat format = AudioFileFormat::Wave); - - //============================================================= - /** @Returns the sample rate */ - uint32_t getSampleRate() const; - - /** @Returns the number of audio channels in the buffer */ - int getNumChannels() const; - - /** @Returns true if the audio file is mono */ - bool isMono() const; - - /** @Returns true if the audio file is stereo */ - bool isStereo() const; - - /** @Returns the bit depth of each sample */ - int getBitDepth() const; - - /** @Returns the number of samples per channel */ - int getNumSamplesPerChannel() const; - - /** @Returns the length in seconds of the audio file based on the number of samples and sample rate */ - double getLengthInSeconds() const; - - /** Prints a summary of the audio file to the console */ - void printSummary() const; - - //============================================================= - - /** Set the audio buffer for this AudioFile by copying samples from another buffer. - * @Returns true if the buffer was copied successfully. - */ - bool setAudioBuffer (AudioBuffer& newBuffer); - - /** Sets the audio buffer to a given number of channels and number of samples per channel. This will try to preserve - * the existing audio, adding zeros to any new channels or new samples in a given channel. - */ - void setAudioBufferSize (int numChannels, int numSamples); - - /** Sets the number of samples per channel in the audio buffer. This will try to preserve - * the existing audio, adding zeros to new samples in a given channel if the number of samples is increased. - */ - void setNumSamplesPerChannel (int numSamples); - - /** Sets the number of channels. New channels will have the correct number of samples and be initialised to zero */ - void setNumChannels (int numChannels); - - /** Sets the bit depth for the audio file. If you use the save() function, this bit depth rate will be used */ - void setBitDepth (int numBitsPerSample); - - /** Sets the sample rate for the audio file. If you use the save() function, this sample rate will be used */ - void setSampleRate (uint32_t newSampleRate); - - //============================================================= - /** Sets whether the library should log error messages to the console. By default this is true */ - void shouldLogErrorsToConsole (bool logErrors); - - //============================================================= - /** A vector of vectors holding the audio samples for the AudioFile. You can - * access the samples by channel and then by sample index, i.e: - * - * samples[channel][sampleIndex] - */ - AudioBuffer samples; - - //============================================================= - /** An optional iXML chunk that can be added to the AudioFile. - */ - std::string iXMLChunk; - -private: - - //============================================================= - enum class Endianness - { - LittleEndian, - BigEndian - }; - - //============================================================= - AudioFileFormat determineAudioFileFormat (std::vector& fileData); - bool decodeWaveFile (std::vector& fileData); - bool decodeAiffFile (std::vector& fileData); - - //============================================================= - bool saveToWaveFile (std::string filePath); - bool saveToAiffFile (std::string filePath); - - //============================================================= - void clearAudioBuffer(); - - //============================================================= - int32_t fourBytesToInt (std::vector& source, int startIndex, Endianness endianness = Endianness::LittleEndian); - int16_t twoBytesToInt (std::vector& source, int startIndex, Endianness endianness = Endianness::LittleEndian); - int getIndexOfString (std::vector& source, std::string s); - int getIndexOfChunk (std::vector& source, const std::string& chunkHeaderID, int startIndex, Endianness endianness = Endianness::LittleEndian); - - //============================================================= - T sixteenBitIntToSample (int16_t sample); - int16_t sampleToSixteenBitInt (T sample); - - //============================================================= - uint8_t sampleToSingleByte (T sample); - T singleByteToSample (uint8_t sample); - - uint32_t getAiffSampleRate (std::vector& fileData, int sampleRateStartIndex); - bool tenByteMatch (std::vector& v1, int startIndex1, std::vector& v2, int startIndex2); - void addSampleRateToAiffData (std::vector& fileData, uint32_t sampleRate); - T clamp (T v1, T minValue, T maxValue); - - //============================================================= - void addStringToFileData (std::vector& fileData, std::string s); - void addInt32ToFileData (std::vector& fileData, int32_t i, Endianness endianness = Endianness::LittleEndian); - void addInt16ToFileData (std::vector& fileData, int16_t i, Endianness endianness = Endianness::LittleEndian); - - //============================================================= - bool writeDataToFile (std::vector& fileData, std::string filePath); - - //============================================================= - void reportError (std::string errorMessage); - - //============================================================= - AudioFileFormat audioFileFormat; - uint32_t sampleRate; - int bitDepth; - bool logErrorsToConsole {true}; - bool rawSamples; -}; - - -//============================================================= -// Pre-defined 10-byte representations of common sample rates -static std::unordered_map > aiffSampleRateTable = { - {8000, {64, 11, 250, 0, 0, 0, 0, 0, 0, 0}}, - {11025, {64, 12, 172, 68, 0, 0, 0, 0, 0, 0}}, - {16000, {64, 12, 250, 0, 0, 0, 0, 0, 0, 0}}, - {22050, {64, 13, 172, 68, 0, 0, 0, 0, 0, 0}}, - {32000, {64, 13, 250, 0, 0, 0, 0, 0, 0, 0}}, - {37800, {64, 14, 147, 168, 0, 0, 0, 0, 0, 0}}, - {44056, {64, 14, 172, 24, 0, 0, 0, 0, 0, 0}}, - {44100, {64, 14, 172, 68, 0, 0, 0, 0, 0, 0}}, - {47250, {64, 14, 184, 146, 0, 0, 0, 0, 0, 0}}, - {48000, {64, 14, 187, 128, 0, 0, 0, 0, 0, 0}}, - {50000, {64, 14, 195, 80, 0, 0, 0, 0, 0, 0}}, - {50400, {64, 14, 196, 224, 0, 0, 0, 0, 0, 0}}, - {88200, {64, 15, 172, 68, 0, 0, 0, 0, 0, 0}}, - {96000, {64, 15, 187, 128, 0, 0, 0, 0, 0, 0}}, - {176400, {64, 16, 172, 68, 0, 0, 0, 0, 0, 0}}, - {192000, {64, 16, 187, 128, 0, 0, 0, 0, 0, 0}}, - {352800, {64, 17, 172, 68, 0, 0, 0, 0, 0, 0}}, - {2822400, {64, 20, 172, 68, 0, 0, 0, 0, 0, 0}}, - {5644800, {64, 21, 172, 68, 0, 0, 0, 0, 0, 0}} -}; - -//============================================================= -enum WavAudioFormat -{ - PCM = 0x0001, - IEEEFloat = 0x0003, - ALaw = 0x0006, - MULaw = 0x0007, - Extensible = 0xFFFE -}; - -//============================================================= -enum AIFFAudioFormat -{ - Uncompressed, - Compressed, - Error -}; - -//============================================================= -/* IMPLEMENTATION */ -//============================================================= - -//============================================================= -template -AudioFile::AudioFile() -{ - // static_assert(std::is_floating_point::value, "ERROR: This version of AudioFile only supports floating point sample formats"); - if (std::is_floating_point::value) { - rawSamples = false; - bitDepth = 16; - } - else { - rawSamples = true; - bitDepth = sizeof(T) * 8; - } - - sampleRate = 44100; - samples.resize (1); - samples[0].resize (0); - audioFileFormat = AudioFileFormat::NotLoaded; -} - -//============================================================= -template -AudioFile::AudioFile (std::string filePath) - : AudioFile() -{ - load (filePath); -} - -//============================================================= -template -uint32_t AudioFile::getSampleRate() const -{ - return sampleRate; -} - -//============================================================= -template -int AudioFile::getNumChannels() const -{ - return (int)samples.size(); -} - -//============================================================= -template -bool AudioFile::isMono() const -{ - return getNumChannels() == 1; -} - -//============================================================= -template -bool AudioFile::isStereo() const -{ - return getNumChannels() == 2; -} - -//============================================================= -template -int AudioFile::getBitDepth() const -{ - return bitDepth; -} - -//============================================================= -template -int AudioFile::getNumSamplesPerChannel() const -{ - if (samples.size() > 0) - return (int) samples[0].size(); - else - return 0; -} - -//============================================================= -template -double AudioFile::getLengthInSeconds() const -{ - return (double)getNumSamplesPerChannel() / (double)sampleRate; -} - -//============================================================= -template -void AudioFile::printSummary() const -{ - std::cout << "|======================================|" << std::endl; - std::cout << "Num Channels: " << getNumChannels() << std::endl; - std::cout << "Num Samples Per Channel: " << getNumSamplesPerChannel() << std::endl; - std::cout << "Sample Rate: " << sampleRate << std::endl; - std::cout << "Bit Depth: " << bitDepth << std::endl; - std::cout << "Length in Seconds: " << getLengthInSeconds() << std::endl; - std::cout << "|======================================|" << std::endl; -} - -//============================================================= -template -bool AudioFile::setAudioBuffer (AudioBuffer& newBuffer) -{ - int numChannels = (int)newBuffer.size(); - - if (numChannels <= 0) - { - assert (false && "The buffer your are trying to use has no channels"); - return false; - } - - size_t numSamples = newBuffer[0].size(); - - // set the number of channels - samples.resize (newBuffer.size()); - - for (int k = 0; k < getNumChannels(); k++) - { - assert (newBuffer[k].size() == numSamples); - - samples[k].resize (numSamples); - - for (size_t i = 0; i < numSamples; i++) - { - samples[k][i] = newBuffer[k][i]; - } - } - - return true; -} - -//============================================================= -template -void AudioFile::setAudioBufferSize (int numChannels, int numSamples) -{ - samples.resize (numChannels); - setNumSamplesPerChannel (numSamples); -} - -//============================================================= -template -void AudioFile::setNumSamplesPerChannel (int numSamples) -{ - int originalSize = getNumSamplesPerChannel(); - - for (int i = 0; i < getNumChannels();i++) - { - samples[i].resize (numSamples); - - // set any new samples to zero - if (numSamples > originalSize) - std::fill (samples[i].begin() + originalSize, samples[i].end(), (T)0.); - } -} - -//============================================================= -template -void AudioFile::setNumChannels (int numChannels) -{ - int originalNumChannels = getNumChannels(); - int originalNumSamplesPerChannel = getNumSamplesPerChannel(); - - samples.resize (numChannels); - - // make sure any new channels are set to the right size - // and filled with zeros - if (numChannels > originalNumChannels) - { - for (int i = originalNumChannels; i < numChannels; i++) - { - samples[i].resize (originalNumSamplesPerChannel); - std::fill (samples[i].begin(), samples[i].end(), (T)0.); - } - } -} - -//============================================================= -template -void AudioFile::setBitDepth (int numBitsPerSample) -{ - bitDepth = numBitsPerSample; -} - -//============================================================= -template -void AudioFile::setSampleRate (uint32_t newSampleRate) -{ - sampleRate = newSampleRate; -} - -//============================================================= -template -void AudioFile::shouldLogErrorsToConsole (bool logErrors) -{ - logErrorsToConsole = logErrors; -} - -//============================================================= -template -bool AudioFile::load (std::string filePath) -{ - std::ifstream file (filePath, std::ios::binary); - - // check the file exists - if (! file.good()) - { - reportError ("ERROR: File doesn't exist or otherwise can't load file\n" + filePath); - return false; - } - - std::vector fileData; - - file.unsetf (std::ios::skipws); - - file.seekg (0, std::ios::end); - size_t length = file.tellg(); - file.seekg (0, std::ios::beg); - - // allocate - fileData.resize (length); - - file.read(reinterpret_cast (fileData.data()), length); - file.close(); - - if (file.gcount() != length) - { - reportError ("ERROR: Couldn't read entire file\n" + filePath); - return false; - } - - // get audio file format - audioFileFormat = determineAudioFileFormat (fileData); - - if (audioFileFormat == AudioFileFormat::Wave) - { - return decodeWaveFile (fileData); - } - else if (audioFileFormat == AudioFileFormat::Aiff) - { - return decodeAiffFile (fileData); - } - else - { - reportError ("Audio File Type: Error"); - return false; - } -} - -//============================================================= -template -bool AudioFile::decodeWaveFile (std::vector& fileData) -{ - // ----------------------------------------------------------- - // HEADER CHUNK - std::string headerChunkID (fileData.begin(), fileData.begin() + 4); - //int32_t fileSizeInBytes = fourBytesToInt (fileData, 4) + 8; - std::string format (fileData.begin() + 8, fileData.begin() + 12); - - // ----------------------------------------------------------- - // try and find the start points of key chunks - int indexOfDataChunk = getIndexOfChunk (fileData, "data", 12); - int indexOfFormatChunk = getIndexOfChunk (fileData, "fmt ", 12); - int indexOfXMLChunk = getIndexOfChunk (fileData, "iXML", 12); - - // if we can't find the data or format chunks, or the IDs/formats don't seem to be as expected - // then it is unlikely we'll able to read this file, so abort - if (indexOfDataChunk == -1 || indexOfFormatChunk == -1 || headerChunkID != "RIFF" || format != "WAVE") - { - reportError ("ERROR: this doesn't seem to be a valid .WAV file"); - return false; - } - - // ----------------------------------------------------------- - // FORMAT CHUNK - int f = indexOfFormatChunk; - std::string formatChunkID (fileData.begin() + f, fileData.begin() + f + 4); - //int32_t formatChunkSize = fourBytesToInt (fileData, f + 4); - uint16_t audioFormat = twoBytesToInt (fileData, f + 8); - uint16_t numChannels = twoBytesToInt (fileData, f + 10); - sampleRate = (uint32_t) fourBytesToInt (fileData, f + 12); - uint32_t numBytesPerSecond = fourBytesToInt (fileData, f + 16); - uint16_t numBytesPerBlock = twoBytesToInt (fileData, f + 20); - bitDepth = (int) twoBytesToInt (fileData, f + 22); - - uint16_t numBytesPerSample = static_cast (bitDepth) / 8; - - // check that the audio format is PCM or Float or extensible - if (audioFormat != WavAudioFormat::PCM && audioFormat != WavAudioFormat::IEEEFloat && audioFormat != WavAudioFormat::Extensible) - { - reportError ("ERROR: this .WAV file is encoded in a format that this library does not support at present"); - return false; - } - - // check the number of channels is mono or stereo - if (numChannels < 1 || numChannels > 128) - { - reportError ("ERROR: this WAV file seems to be an invalid number of channels (or corrupted?)"); - return false; - } - - // check header data is consistent - if (numBytesPerSecond != static_cast ((numChannels * sampleRate * bitDepth) / 8) || numBytesPerBlock != (numChannels * numBytesPerSample)) - { - reportError ("ERROR: the header data in this WAV file seems to be inconsistent"); - return false; - } - - // check bit depth is either 8, 16, 24 or 32 bit - if (bitDepth != 8 && bitDepth != 16 && bitDepth != 24 && bitDepth != 32) - { - reportError ("ERROR: this file has a bit depth that is not 8, 16, 24 or 32 bits"); - return false; - } - - // ----------------------------------------------------------- - // DATA CHUNK - int d = indexOfDataChunk; - std::string dataChunkID (fileData.begin() + d, fileData.begin() + d + 4); - int32_t dataChunkSize = fourBytesToInt (fileData, d + 4); - - int numSamples = dataChunkSize / (numChannels * bitDepth / 8); - int samplesStartIndex = indexOfDataChunk + 8; - - clearAudioBuffer(); - samples.resize (numChannels); - - for (int i = 0; i < numSamples; i++) - { - for (int channel = 0; channel < numChannels; channel++) - { - int sampleIndex = samplesStartIndex + (numBytesPerBlock * i) + channel * numBytesPerSample; - - if ((sampleIndex + (bitDepth / 8) - 1) >= fileData.size()) - { - reportError ("ERROR: read file error as the metadata indicates more samples than there are in the file data"); - return false; - } - - if (bitDepth == 8) - { - T sample = singleByteToSample (fileData[sampleIndex]); - samples[channel].push_back (sample); - } - else if (bitDepth == 16) - { - int16_t sampleAsInt = twoBytesToInt (fileData, sampleIndex); - T sample = sixteenBitIntToSample (sampleAsInt); - samples[channel].push_back (sample); - } - else if (bitDepth == 24) - { - int32_t sampleAsInt = 0; - sampleAsInt = (fileData[sampleIndex + 2] << 16) | (fileData[sampleIndex + 1] << 8) | fileData[sampleIndex]; - - if (sampleAsInt & 0x800000) // if the 24th bit is set, this is a negative number in 24-bit world - sampleAsInt = sampleAsInt | ~0xFFFFFF; // so make sure sign is extended to the 32 bit float - - T sample = (T)sampleAsInt / (T)8388608.; - samples[channel].push_back (sample); - } - else if (bitDepth == 32) - { - int32_t sampleAsInt = fourBytesToInt (fileData, sampleIndex); - T sample; - - if (audioFormat == WavAudioFormat::IEEEFloat) - sample = (T)reinterpret_cast (sampleAsInt); - else // assume PCM - sample = (T) sampleAsInt / static_cast (std::numeric_limits::max()); - - samples[channel].push_back (sample); - } - else - { - assert (false); - } - } - } - - // ----------------------------------------------------------- - // iXML CHUNK - if (indexOfXMLChunk != -1) - { - int32_t chunkSize = fourBytesToInt (fileData, indexOfXMLChunk + 4); - iXMLChunk = std::string ((const char*) &fileData[indexOfXMLChunk + 8], chunkSize); - } - - return true; -} - -//============================================================= -template -bool AudioFile::decodeAiffFile (std::vector& fileData) -{ - // ----------------------------------------------------------- - // HEADER CHUNK - std::string headerChunkID (fileData.begin(), fileData.begin() + 4); - //int32_t fileSizeInBytes = fourBytesToInt (fileData, 4, Endianness::BigEndian) + 8; - std::string format (fileData.begin() + 8, fileData.begin() + 12); - - int audioFormat = format == "AIFF" ? AIFFAudioFormat::Uncompressed : format == "AIFC" ? AIFFAudioFormat::Compressed : AIFFAudioFormat::Error; - - // ----------------------------------------------------------- - // try and find the start points of key chunks - int indexOfCommChunk = getIndexOfChunk (fileData, "COMM", 12, Endianness::BigEndian); - int indexOfSoundDataChunk = getIndexOfChunk (fileData, "SSND", 12, Endianness::BigEndian); - int indexOfXMLChunk = getIndexOfChunk (fileData, "iXML", 12, Endianness::BigEndian); - - // if we can't find the data or format chunks, or the IDs/formats don't seem to be as expected - // then it is unlikely we'll able to read this file, so abort - if (indexOfSoundDataChunk == -1 || indexOfCommChunk == -1 || headerChunkID != "FORM" || audioFormat == AIFFAudioFormat::Error) - { - reportError ("ERROR: this doesn't seem to be a valid AIFF file"); - return false; - } - - // ----------------------------------------------------------- - // COMM CHUNK - int p = indexOfCommChunk; - std::string commChunkID (fileData.begin() + p, fileData.begin() + p + 4); - //int32_t commChunkSize = fourBytesToInt (fileData, p + 4, Endianness::BigEndian); - int16_t numChannels = twoBytesToInt (fileData, p + 8, Endianness::BigEndian); - int32_t numSamplesPerChannel = fourBytesToInt (fileData, p + 10, Endianness::BigEndian); - bitDepth = (int) twoBytesToInt (fileData, p + 14, Endianness::BigEndian); - sampleRate = getAiffSampleRate (fileData, p + 16); - - // check the sample rate was properly decoded - if (sampleRate == 0) - { - reportError ("ERROR: this AIFF file has an unsupported sample rate"); - return false; - } - - // check the number of channels is mono or stereo - if (numChannels < 1 ||numChannels > 2) - { - reportError ("ERROR: this AIFF file seems to be neither mono nor stereo (perhaps multi-track, or corrupted?)"); - return false; - } - - // check bit depth is either 8, 16, 24 or 32-bit - if (bitDepth != 8 && bitDepth != 16 && bitDepth != 24 && bitDepth != 32) - { - reportError ("ERROR: this file has a bit depth that is not 8, 16, 24 or 32 bits"); - return false; - } - - // ----------------------------------------------------------- - // SSND CHUNK - int s = indexOfSoundDataChunk; - std::string soundDataChunkID (fileData.begin() + s, fileData.begin() + s + 4); - int32_t soundDataChunkSize = fourBytesToInt (fileData, s + 4, Endianness::BigEndian); - int32_t offset = fourBytesToInt (fileData, s + 8, Endianness::BigEndian); - //int32_t blockSize = fourBytesToInt (fileData, s + 12, Endianness::BigEndian); - - int numBytesPerSample = bitDepth / 8; - int numBytesPerFrame = numBytesPerSample * numChannels; - int totalNumAudioSampleBytes = numSamplesPerChannel * numBytesPerFrame; - int samplesStartIndex = s + 16 + (int)offset; - - // sanity check the data - if ((soundDataChunkSize - 8) != totalNumAudioSampleBytes || totalNumAudioSampleBytes > static_cast(fileData.size() - samplesStartIndex)) - { - reportError ("ERROR: the metadatafor this file doesn't seem right"); - return false; - } - - clearAudioBuffer(); - samples.resize (numChannels); - - for (int i = 0; i < numSamplesPerChannel; i++) - { - for (int channel = 0; channel < numChannels; channel++) - { - int sampleIndex = samplesStartIndex + (numBytesPerFrame * i) + channel * numBytesPerSample; - - if ((sampleIndex + (bitDepth / 8) - 1) >= fileData.size()) - { - reportError ("ERROR: read file error as the metadata indicates more samples than there are in the file data"); - return false; - } - - if (bitDepth == 8) - { - int8_t sampleAsSigned8Bit = (int8_t)fileData[sampleIndex]; - T sample = (T)sampleAsSigned8Bit / (T)128.; - samples[channel].push_back (sample); - } - else if (bitDepth == 16) - { - int16_t sampleAsInt = twoBytesToInt (fileData, sampleIndex, Endianness::BigEndian); - T sample = sixteenBitIntToSample (sampleAsInt); - samples[channel].push_back (sample); - } - else if (bitDepth == 24) - { - int32_t sampleAsInt = 0; - sampleAsInt = (fileData[sampleIndex] << 16) | (fileData[sampleIndex + 1] << 8) | fileData[sampleIndex + 2]; - - if (sampleAsInt & 0x800000) // if the 24th bit is set, this is a negative number in 24-bit world - sampleAsInt = sampleAsInt | ~0xFFFFFF; // so make sure sign is extended to the 32 bit float - - T sample = (T)sampleAsInt / (T)8388608.; - samples[channel].push_back (sample); - } - else if (bitDepth == 32) - { - int32_t sampleAsInt = fourBytesToInt (fileData, sampleIndex, Endianness::BigEndian); - T sample; - - if (audioFormat == AIFFAudioFormat::Compressed) - sample = (T)reinterpret_cast (sampleAsInt); - else // assume uncompressed - sample = (T) sampleAsInt / static_cast (std::numeric_limits::max()); - - samples[channel].push_back (sample); - } - else - { - assert (false); - } - } - } - - // ----------------------------------------------------------- - // iXML CHUNK - if (indexOfXMLChunk != -1) - { - int32_t chunkSize = fourBytesToInt (fileData, indexOfXMLChunk + 4); - iXMLChunk = std::string ((const char*) &fileData[indexOfXMLChunk + 8], chunkSize); - } - - return true; -} - -//============================================================= -template -uint32_t AudioFile::getAiffSampleRate (std::vector& fileData, int sampleRateStartIndex) -{ - for (auto it : aiffSampleRateTable) - { - if (tenByteMatch (fileData, sampleRateStartIndex, it.second, 0)) - return it.first; - } - - return 0; -} - -//============================================================= -template -bool AudioFile::tenByteMatch (std::vector& v1, int startIndex1, std::vector& v2, int startIndex2) -{ - for (int i = 0; i < 10; i++) - { - if (v1[startIndex1 + i] != v2[startIndex2 + i]) - return false; - } - - return true; -} - -//============================================================= -template -void AudioFile::addSampleRateToAiffData (std::vector& fileData, uint32_t sampleRate) -{ - if (aiffSampleRateTable.count (sampleRate) > 0) - { - for (int i = 0; i < 10; i++) - fileData.push_back (aiffSampleRateTable[sampleRate][i]); - } -} - -//============================================================= -template -bool AudioFile::save (std::string filePath, AudioFileFormat format) -{ - if (format == AudioFileFormat::Wave) - { - return saveToWaveFile (filePath); - } - else if (format == AudioFileFormat::Aiff) - { - return saveToAiffFile (filePath); - } - - return false; -} - -//============================================================= -template -bool AudioFile::saveToWaveFile (std::string filePath) -{ - std::vector fileData; - - int32_t dataChunkSize = getNumSamplesPerChannel() * (getNumChannels() * bitDepth / 8); - int16_t audioFormat = bitDepth == 32 ? WavAudioFormat::IEEEFloat : WavAudioFormat::PCM; - int32_t formatChunkSize = audioFormat == WavAudioFormat::PCM ? 16 : 18; - int32_t iXMLChunkSize = static_cast (iXMLChunk.size()); - - // ----------------------------------------------------------- - // HEADER CHUNK - addStringToFileData (fileData, "RIFF"); - - // The file size in bytes is the header chunk size (4, not counting RIFF and WAVE) + the format - // chunk size (24) + the metadata part of the data chunk plus the actual data chunk size - int32_t fileSizeInBytes = 4 + formatChunkSize + 8 + 8 + dataChunkSize; - if (iXMLChunkSize > 0) - { - fileSizeInBytes += (8 + iXMLChunkSize); - } - - addInt32ToFileData (fileData, fileSizeInBytes); - - addStringToFileData (fileData, "WAVE"); - - // ----------------------------------------------------------- - // FORMAT CHUNK - addStringToFileData (fileData, "fmt "); - addInt32ToFileData (fileData, formatChunkSize); // format chunk size (16 for PCM) - addInt16ToFileData (fileData, audioFormat); // audio format - addInt16ToFileData (fileData, (int16_t)getNumChannels()); // num channels - addInt32ToFileData (fileData, (int32_t)sampleRate); // sample rate - - int32_t numBytesPerSecond = (int32_t) ((getNumChannels() * sampleRate * bitDepth) / 8); - addInt32ToFileData (fileData, numBytesPerSecond); - - int16_t numBytesPerBlock = getNumChannels() * (bitDepth / 8); - addInt16ToFileData (fileData, numBytesPerBlock); - - addInt16ToFileData (fileData, (int16_t)bitDepth); - - if (audioFormat == WavAudioFormat::IEEEFloat) - addInt16ToFileData (fileData, 0); // extension size - - // ----------------------------------------------------------- - // DATA CHUNK - addStringToFileData (fileData, "data"); - addInt32ToFileData (fileData, dataChunkSize); - - for (int i = 0; i < getNumSamplesPerChannel(); i++) - { - for (int channel = 0; channel < getNumChannels(); channel++) - { - if (bitDepth == 8) - { - uint8_t byte = rawSamples ? samples[channel][i] : sampleToSingleByte (samples[channel][i]); - fileData.push_back (byte); - } - else if (bitDepth == 16) - { - int16_t sampleAsInt = rawSamples ? samples[channel][i] : sampleToSixteenBitInt (samples[channel][i]); - addInt16ToFileData (fileData, sampleAsInt); - } - else if (bitDepth == 24) - { - int32_t sampleAsIntAgain = rawSamples ? samples[channel][i] : (int32_t) (samples[channel][i] * (T)8388608.); - - uint8_t bytes[3]; - bytes[2] = (uint8_t) (sampleAsIntAgain >> 16) & 0xFF; - bytes[1] = (uint8_t) (sampleAsIntAgain >> 8) & 0xFF; - bytes[0] = (uint8_t) sampleAsIntAgain & 0xFF; - - fileData.push_back (bytes[0]); - fileData.push_back (bytes[1]); - fileData.push_back (bytes[2]); - } - else if (bitDepth == 32) - { - int32_t sampleAsInt; - - if (audioFormat == WavAudioFormat::IEEEFloat) - sampleAsInt = (int32_t) reinterpret_cast (samples[channel][i]); - else // assume PCM - sampleAsInt = rawSamples ? samples[channel][i] : (int32_t) (samples[channel][i] * std::numeric_limits::max()); - - addInt32ToFileData (fileData, sampleAsInt, Endianness::LittleEndian); - } - else - { - assert (false && "Trying to write a file with unsupported bit depth"); - return false; - } - } - } - - // ----------------------------------------------------------- - // iXML CHUNK - if (iXMLChunkSize > 0) - { - addStringToFileData (fileData, "iXML"); - addInt32ToFileData (fileData, iXMLChunkSize); - addStringToFileData (fileData, iXMLChunk); - } - - // check that the various sizes we put in the metadata are correct - if (fileSizeInBytes != static_cast (fileData.size() - 8) || dataChunkSize != (getNumSamplesPerChannel() * getNumChannels() * (bitDepth / 8))) - { - reportError ("ERROR: couldn't save file to " + filePath); - return false; - } - - // try to write the file - return writeDataToFile (fileData, filePath); -} - -//============================================================= -template -bool AudioFile::saveToAiffFile (std::string filePath) -{ - std::vector fileData; - - int32_t numBytesPerSample = bitDepth / 8; - int32_t numBytesPerFrame = numBytesPerSample * getNumChannels(); - int32_t totalNumAudioSampleBytes = getNumSamplesPerChannel() * numBytesPerFrame; - int32_t soundDataChunkSize = totalNumAudioSampleBytes + 8; - int32_t iXMLChunkSize = static_cast (iXMLChunk.size()); - - // ----------------------------------------------------------- - // HEADER CHUNK - addStringToFileData (fileData, "FORM"); - - // The file size in bytes is the header chunk size (4, not counting FORM and AIFF) + the COMM - // chunk size (26) + the metadata part of the SSND chunk plus the actual data chunk size - int32_t fileSizeInBytes = 4 + 26 + 16 + totalNumAudioSampleBytes; - if (iXMLChunkSize > 0) - { - fileSizeInBytes += (8 + iXMLChunkSize); - } - - addInt32ToFileData (fileData, fileSizeInBytes, Endianness::BigEndian); - - addStringToFileData (fileData, "AIFF"); - - // ----------------------------------------------------------- - // COMM CHUNK - addStringToFileData (fileData, "COMM"); - addInt32ToFileData (fileData, 18, Endianness::BigEndian); // commChunkSize - addInt16ToFileData (fileData, getNumChannels(), Endianness::BigEndian); // num channels - addInt32ToFileData (fileData, getNumSamplesPerChannel(), Endianness::BigEndian); // num samples per channel - addInt16ToFileData (fileData, bitDepth, Endianness::BigEndian); // bit depth - addSampleRateToAiffData (fileData, sampleRate); - - // ----------------------------------------------------------- - // SSND CHUNK - addStringToFileData (fileData, "SSND"); - addInt32ToFileData (fileData, soundDataChunkSize, Endianness::BigEndian); - addInt32ToFileData (fileData, 0, Endianness::BigEndian); // offset - addInt32ToFileData (fileData, 0, Endianness::BigEndian); // block size - - for (int i = 0; i < getNumSamplesPerChannel(); i++) - { - for (int channel = 0; channel < getNumChannels(); channel++) - { - if (bitDepth == 8) - { - uint8_t byte = sampleToSingleByte (samples[channel][i]); - fileData.push_back (byte); - } - else if (bitDepth == 16) - { - int16_t sampleAsInt = sampleToSixteenBitInt (samples[channel][i]); - addInt16ToFileData (fileData, sampleAsInt, Endianness::BigEndian); - } - else if (bitDepth == 24) - { - int32_t sampleAsIntAgain = (int32_t) (samples[channel][i] * (T)8388608.); - - uint8_t bytes[3]; - bytes[0] = (uint8_t) (sampleAsIntAgain >> 16) & 0xFF; - bytes[1] = (uint8_t) (sampleAsIntAgain >> 8) & 0xFF; - bytes[2] = (uint8_t) sampleAsIntAgain & 0xFF; - - fileData.push_back (bytes[0]); - fileData.push_back (bytes[1]); - fileData.push_back (bytes[2]); - } - else if (bitDepth == 32) - { - // write samples as signed integers (no implementation yet for floating point, but looking at WAV implementation should help) - int32_t sampleAsInt = (int32_t) (samples[channel][i] * std::numeric_limits::max()); - addInt32ToFileData (fileData, sampleAsInt, Endianness::BigEndian); - } - else - { - assert (false && "Trying to write a file with unsupported bit depth"); - return false; - } - } - } - - // ----------------------------------------------------------- - // iXML CHUNK - if (iXMLChunkSize > 0) - { - addStringToFileData (fileData, "iXML"); - addInt32ToFileData (fileData, iXMLChunkSize, Endianness::BigEndian); - addStringToFileData (fileData, iXMLChunk); - } - - // check that the various sizes we put in the metadata are correct - if (fileSizeInBytes != static_cast (fileData.size() - 8) || soundDataChunkSize != getNumSamplesPerChannel() * numBytesPerFrame + 8) - { - reportError ("ERROR: couldn't save file to " + filePath); - return false; - } - - // try to write the file - return writeDataToFile (fileData, filePath); -} - -//============================================================= -template -bool AudioFile::writeDataToFile (std::vector& fileData, std::string filePath) -{ - std::ofstream outputFile (filePath, std::ios::binary); - - if (outputFile.is_open()) - { - for (size_t i = 0; i < fileData.size(); i++) - { - char value = (char) fileData[i]; - outputFile.write (&value, sizeof (char)); - } - - outputFile.close(); - - return true; - } - - return false; -} - -//============================================================= -template -void AudioFile::addStringToFileData (std::vector& fileData, std::string s) -{ - for (size_t i = 0; i < s.length();i++) - fileData.push_back ((uint8_t) s[i]); -} - -//============================================================= -template -void AudioFile::addInt32ToFileData (std::vector& fileData, int32_t i, Endianness endianness) -{ - uint8_t bytes[4]; - - if (endianness == Endianness::LittleEndian) - { - bytes[3] = (i >> 24) & 0xFF; - bytes[2] = (i >> 16) & 0xFF; - bytes[1] = (i >> 8) & 0xFF; - bytes[0] = i & 0xFF; - } - else - { - bytes[0] = (i >> 24) & 0xFF; - bytes[1] = (i >> 16) & 0xFF; - bytes[2] = (i >> 8) & 0xFF; - bytes[3] = i & 0xFF; - } - - for (int i = 0; i < 4; i++) - fileData.push_back (bytes[i]); -} - -//============================================================= -template -void AudioFile::addInt16ToFileData (std::vector& fileData, int16_t i, Endianness endianness) -{ - uint8_t bytes[2]; - - if (endianness == Endianness::LittleEndian) - { - bytes[1] = (i >> 8) & 0xFF; - bytes[0] = i & 0xFF; - } - else - { - bytes[0] = (i >> 8) & 0xFF; - bytes[1] = i & 0xFF; - } - - fileData.push_back (bytes[0]); - fileData.push_back (bytes[1]); -} - -//============================================================= -template -void AudioFile::clearAudioBuffer() -{ - for (size_t i = 0; i < samples.size();i++) - { - samples[i].clear(); - } - - samples.clear(); -} - -//============================================================= -template -AudioFileFormat AudioFile::determineAudioFileFormat (std::vector& fileData) -{ - std::string header (fileData.begin(), fileData.begin() + 4); - - if (header == "RIFF") - return AudioFileFormat::Wave; - else if (header == "FORM") - return AudioFileFormat::Aiff; - else - return AudioFileFormat::Error; -} - -//============================================================= -template -int32_t AudioFile::fourBytesToInt (std::vector& source, int startIndex, Endianness endianness) -{ - int32_t result; - - if (endianness == Endianness::LittleEndian) - result = (source[startIndex + 3] << 24) | (source[startIndex + 2] << 16) | (source[startIndex + 1] << 8) | source[startIndex]; - else - result = (source[startIndex] << 24) | (source[startIndex + 1] << 16) | (source[startIndex + 2] << 8) | source[startIndex + 3]; - - return result; -} - -//============================================================= -template -int16_t AudioFile::twoBytesToInt (std::vector& source, int startIndex, Endianness endianness) -{ - int16_t result; - - if (endianness == Endianness::LittleEndian) - result = (source[startIndex + 1] << 8) | source[startIndex]; - else - result = (source[startIndex] << 8) | source[startIndex + 1]; - - return result; -} - -//============================================================= -template -int AudioFile::getIndexOfString (std::vector& source, std::string stringToSearchFor) -{ - int index = -1; - int stringLength = (int)stringToSearchFor.length(); - - for (size_t i = 0; i < source.size() - stringLength;i++) - { - std::string section (source.begin() + i, source.begin() + i + stringLength); - - if (section == stringToSearchFor) - { - index = static_cast (i); - break; - } - } - - return index; -} - -//============================================================= -template -int AudioFile::getIndexOfChunk (std::vector& source, const std::string& chunkHeaderID, int startIndex, Endianness endianness) -{ - constexpr int dataLen = 4; - if (chunkHeaderID.size() != dataLen) - { - assert (false && "Invalid chunk header ID string"); - return -1; - } - - int i = startIndex; - while (i < source.size() - dataLen) - { - if (memcmp (&source[i], chunkHeaderID.data(), dataLen) == 0) - { - return i; - } - - i += dataLen; - auto chunkSize = fourBytesToInt (source, i, endianness); - i += (dataLen + chunkSize); - } - - return -1; -} - -//============================================================= -template -T AudioFile::sixteenBitIntToSample (int16_t sample) -{ - return static_cast (sample) / static_cast (32768.); -} - -//============================================================= -template -int16_t AudioFile::sampleToSixteenBitInt (T sample) -{ - sample = clamp (sample, -1., 1.); - return static_cast (sample * 32767.); -} - -//============================================================= -template -uint8_t AudioFile::sampleToSingleByte (T sample) -{ - sample = clamp (sample, -1., 1.); - sample = (sample + 1.) / 2.; - return static_cast (sample * 255.); -} - -//============================================================= -template -T AudioFile::singleByteToSample (uint8_t sample) -{ - return static_cast (sample - 128) / static_cast (128.); -} - -//============================================================= -template -T AudioFile::clamp (T value, T minValue, T maxValue) -{ - value = std::min (value, maxValue); - value = std::max (value, minValue); - return value; -} - -//============================================================= -template -void AudioFile::reportError (std::string errorMessage) -{ - if (logErrorsToConsole) - std::cout << errorMessage << std::endl; -} - -#if defined (_MSC_VER) - __pragma(warning (pop)) -#elif defined (__GNUC__) - _Pragma("GCC diagnostic pop") -#endif - -#endif /* AudioFile_h */