aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/include/asiomodern
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/include/asiomodern
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/include/asiomodern')
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/OpenMPT.txt1
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/.clang-format153
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIO.hpp16
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOConfig.hpp385
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOCore.hpp469
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOModern.hpp960
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSampleConvert.hpp1100
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSystemWindows.hpp511
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSystemWindowsSEH.hpp283
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVerifyABI.hpp127
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVersion.hpp132
-rw-r--r--Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOstdcxx20bit.hpp48
12 files changed, 4185 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/OpenMPT.txt b/Src/external_dependencies/openmpt-trunk/include/asiomodern/OpenMPT.txt
new file mode 100644
index 00000000..3879702b
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/OpenMPT.txt
@@ -0,0 +1 @@
+ASIO::Modern v0.12.5
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/.clang-format b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/.clang-format
new file mode 100644
index 00000000..db82ab66
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/.clang-format
@@ -0,0 +1,153 @@
+# clang-format 13
+
+Language: Cpp
+Standard: c++20
+
+AccessModifierOffset: -4 #?
+AlignAfterOpenBracket: AlwaysBreak
+AlignArrayOfStructures: Left
+AlignConsecutiveAssignments: true
+AlignConsecutiveBitFields: true
+AlignConsecutiveDeclarations: true
+AlignConsecutiveMacros: true
+AlignEscapedNewlines: DontAlign
+AlignOperands: AlignAfterOperator
+AlignTrailingComments: true
+AllowAllArgumentsOnNextLine: true
+AllowAllConstructorInitializersOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortEnumsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLambdasOnASingleLine: Inline
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: Yes
+AttributeMacros: []
+BinPackArguments: true
+BinPackParameters: false
+BitFieldColonSpacing: Both
+BraceWrapping:
+ AfterCaseLabel: false
+ AfterClass: false
+ AfterControlStatement: MultiLine
+ AfterEnum: false
+ AfterFunction: false
+ AfterNamespace: false
+ #AfterObjCDeclaration
+ AfterStruct: false
+ AfterUnion: false
+ AfterExternBlock: false
+ BeforeCatch: false
+ BeforeElse: false
+ BeforeLambdaBody: false
+ BeforeWhile: false
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: false
+ SplitEmptyNamespace: true
+#BreakAfterJavaFieldAnnotations
+BreakBeforeBinaryOperators: NonAssignment
+BreakBeforeBraces: Custom
+BreakBeforeConceptDeclarations: true
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeComma
+BreakInheritanceList: BeforeComma
+BreakStringLiterals: false
+ColumnLimit: 0
+CommentPragmas: '' #?
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4 #?
+ContinuationIndentWidth: 4 #?
+Cpp11BracedListStyle: true
+DeriveLineEnding: true
+DerivePointerAlignment: false
+EmptyLineAfterAccessModifier: Leave
+EmptyLineBeforeAccessModifier: Leave
+FixNamespaceComments: true
+ForEachMacros: []
+IfMacros: ['']
+IncludeBlocks: Preserve
+IncludeCategories: [] #?
+IncludeIsMainRegex: '' #?
+IncludeIsMainSourceRegex: '' #?
+IndentAccessModifiers: false
+IndentCaseLabels: true
+IndentCaseBlocks: true
+IndentExternBlock: NoIndent
+IndentGotoLabels: false
+IndentPPDirectives: None
+#IndentRequiresClause: true
+InsertTrailingCommas: None
+#BeforeHash
+IndentWidth: 4
+IndentWrappedFunctionNames: true
+#JavaImportGroups
+#JavaScriptQuotes
+#JavaScriptWrapImports
+KeepEmptyLinesAtTheStartOfBlocks: true
+LambdaBodyIndentation: OuterScope
+MacroBlockBegin: '' #?
+MacroBlockEnd: '' #?
+MaxEmptyLinesToKeep: 5
+NamespaceIndentation: None
+NamespaceMacros: [] #?
+#ObjCBinPackProtocolList
+#ObjCBlockIndentWidth
+#ObjCBreakBeforeNestedBlockParam
+#ObjCSpaceAfterProperty
+#ObjCSpaceBeforeProtocolList
+#PenaltyBreakAssignment
+#PenaltyBreakBeforeFirstCallParameter
+#PenaltyBreakComment
+#PenaltyBreakFirstLessLess
+#PenaltyBreakString
+#PenaltyBreakTemplateDeclaration
+#PenaltyExcessCharacter
+#PenaltyIndentedWhitespace
+#PenaltyReturnTypeOnItsOwnLine
+PointerAlignment: Middle
+PPIndentWidth: -1
+#RawStringFormats
+ReferenceAlignment: Pointer
+ReflowComments: false
+ShortNamespaceLines: 1
+SortIncludes: false
+#SortJavaStaticImport
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBlock: true
+SpaceInEmptyParentheses: false
+SpacesInLineCommentPrefix:
+ Minimum: 1
+ Maximum: -1
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInCStyleCastParentheses: false
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: true
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+StatementAttributeLikeMacros: []
+StatementMacros: [ '_Pragma', '__pragma' ] #?
+TabWidth: 4
+TypenameMacros: [] #?
+UseCRLF: false
+UseTab: ForContinuationAndIndentation
+WhitespaceSensitiveMacros:
+ - ASIO_PP_STRINGIFY
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIO.hpp b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIO.hpp
new file mode 100644
index 00000000..891f2e12
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIO.hpp
@@ -0,0 +1,16 @@
+
+#ifndef ASIO_ASIO_HPP
+#define ASIO_ASIO_HPP
+
+
+
+#include "ASIOVersion.hpp"
+#include "ASIOConfig.hpp"
+#include "ASIOCore.hpp"
+#include "ASIOModern.hpp"
+//#include "ASIOSystemWindows.hpp"
+//#include "ASIOSampleConvert.hpp"
+
+
+
+#endif // ASIO_ASIO_HPP
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOConfig.hpp b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOConfig.hpp
new file mode 100644
index 00000000..7ae4e493
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOConfig.hpp
@@ -0,0 +1,385 @@
+
+#ifndef ASIO_ASIOCONFIG_HPP
+#define ASIO_ASIOCONFIG_HPP
+
+
+
+#include "ASIOVersion.hpp"
+
+
+
+#include <algorithm>
+#include <string>
+#include <string_view>
+
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+
+
+
+#if defined(_WIN32)
+#define ASIO_SYSTEM_WINDOWS 1
+#endif
+
+#ifndef ASIO_SYSTEM_WINDOWS
+#define ASIO_SYSTEM_WINDOWS 0
+#endif
+
+
+#if defined(__clang__)
+#define ASIO_COMPILER_CLANG 1
+#elif defined(_MSC_VER)
+#define ASIO_COMPILER_MSVC 1
+#elif defined(__GNUC__)
+#define ASIO_COMPILER_GCC 1
+#endif
+
+#ifndef ASIO_COMPILER_CLANG
+#define ASIO_COMPILER_CLANG 0
+#endif
+#ifndef ASIO_COMPILER_MSVC
+#define ASIO_COMPILER_MSVC 0
+#endif
+#ifndef ASIO_COMPILER_GCC
+#define ASIO_COMPILER_GCC 0
+#endif
+
+
+#if ASIO_COMPILER_MSVC || ASIO_COMPILER_CLANG || ASIO_COMPILER_GCC || ASIO_SYSTEM_WINDOWS
+// assume #pragma pack support on Windows
+#define ASIO_HAVE_PRAGMA_PACK 1
+#else
+#define ASIO_HAVE_PRAGMA_PACK 0
+#endif
+
+
+#if ASIO_COMPILER_MSVC || ASIO_COMPILER_CLANG || ASIO_SYSTEM_WINDOWS
+// assume #pragma comment lib support on Windows
+#define ASIO_HAVE_PRAGMA_COMMENT_LIB 1
+#else
+#define ASIO_HAVE_PRAGMA_COMMENT_LIB 0
+#endif
+
+
+
+#if ASIO_SYSTEM_WINDOWS
+#include <objbase.h>
+#endif // ASIO_SYSTEM_WINDOWS
+
+
+
+namespace ASIO {
+
+
+
+#define ASIO_PP_DEFER(m, ...) m(__VA_ARGS__)
+
+#define ASIO_PP_STRINGIFY(x) #x
+
+#define ASIO_PP_JOIN_HELPER(a, b) a##b
+#define ASIO_PP_JOIN(a, b) ASIO_PP_JOIN_HELPER(a, b)
+
+#define ASIO_PP_UNIQUE_IDENTIFIER(prefix) ASIO_PP_JOIN(prefix, __LINE__)
+
+
+
+#if ASIO_COMPILER_MSVC
+#define ASIO_WARNING(text) __pragma(message(__FILE__ "(" ASIO_PP_DEFER(ASIO_PP_STRINGIFY, __LINE__) "): Warning: " text))
+#elif ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG
+#define ASIO_WARNING(text) _Pragma(MPT_PP_STRINGIFY(GCC warning text))
+#else
+#define ASIO_WARNING(text) \
+ static inline int ASIO_PP_UNIQUE_IDENTIFIER(ASIO_WARNING_NAME)() noexcept { \
+ int warning [[deprecated("Warning: " text)]] = 0; \
+ return warning; \
+ } \
+/**/
+#endif
+
+
+
+#if ASIO_SYSTEM_WINDOWS
+
+
+#if !ASIO_HAVE_PRAGMA_PACK
+#error "ASIO on Windows requires #pragma pack support"
+#endif // !ASIO_HAVE_PRAGMA_PACK
+
+#define ASIO_INTERFACE interface
+
+#if ASIO_COMPILER_MSVC
+#define ASIO_ATTR_DRIVERCALL
+#define ASIO_DRIVERCALL __thiscall
+#elif ASIO_COMPILER_CLANG
+#define ASIO_ATTR_DRIVERCALL
+#define ASIO_DRIVERCALL __thiscall
+#elif ASIO_COMPILER_GCC
+#pragma push_macro("thiscall")
+#ifdef thiscall
+#undef thiscall
+#endif
+#define ASIO_ATTR_DRIVERCALL [[gnu::thiscall]]
+#define ASIO_DRIVERCALL
+#pragma pop_macro("thiscall")
+#else
+#define ASIO_ATTR_DRIVERCALL
+#define ASIO_DRIVERCALL __thiscall
+#endif
+
+#if ASIO_COMPILER_MSVC
+#define ASIO_ATTR_CALL
+#define ASIO_CALL __cdecl
+#elif ASIO_COMPILER_CLANG
+#define ASIO_ATTR_CALL
+#define ASIO_CALL __cdecl
+#elif ASIO_COMPILER_GCC
+#pragma push_macro("cdecl")
+#ifdef cdecl
+#undef cdecl
+#endif
+#define ASIO_ATTR_CALL [[gnu::cdecl]]
+#define ASIO_CALL
+#pragma pop_macro("cdecl")
+#else
+#define ASIO_ATTR_CALL
+#define ASIO_CALL __cdecl
+#endif
+
+
+#else // !ASIO_SYSTEM_WINDOWS
+
+
+#error "Only Windows is supported by this ASIO header"
+
+
+#define ASIO_INTERFACE struct
+
+#define ASIO_ATTR_DRIVERCALL
+#define ASIO_DRIVERCALL
+
+#define ASIO_ATTR_CALL
+#define ASIO_CALL
+
+
+#endif // ASIO_SYSTEM_WINDOWS
+
+
+
+inline namespace Core {
+
+
+
+inline namespace ASIO_VERSION_NAMESPACE {
+
+
+
+#if ASIO_SYSTEM_WINDOWS
+
+
+using SysHandle = void *;
+
+using Byte = std::uint8_t;
+
+using Long = std::int32_t;
+
+using ULong = std::uint32_t;
+
+using LongLong = std::int64_t;
+
+using ULongLong = std::uint64_t;
+
+using Double = double;
+
+using Char = char;
+
+using Padding1 = std::uint8_t;
+
+using PaddingLong = ULong;
+
+
+#else // !ASIO_SYSTEM_WINDOWS
+
+
+#error "Only Windows is supported by this ASIO header"
+
+
+#define ASIO_INTERFACE struct
+
+#define ASIO_ATTR_DRIVERCALL
+#define ASIO_DRIVERCALL
+
+#define ASIO_ATTR_CALL
+#define ASIO_CALL
+
+using SysHandle = void *;
+
+using Byte = unsigned char;
+
+using Long = signed long;
+
+using ULong = unsigned long;
+
+using LongLong = signed long long;
+
+using ULongLong = unsigned long long;
+
+using Double = double;
+
+using Char = char;
+
+using Padding1 = std::uint8_t;
+
+using PaddingLong = ULong;
+
+
+#endif // ASIO_SYSTEM_WINDOWS
+
+
+
+struct Bool {
+private:
+ ULong m_val;
+
+public:
+ constexpr Bool() noexcept
+ : m_val(0) { }
+ constexpr Bool(bool val) noexcept
+ : m_val(val ? 1 : 0) { }
+ constexpr explicit Bool(ULong val) noexcept
+ : m_val(val ? 1 : 0) { }
+ constexpr bool operator!() const noexcept {
+ return m_val ? false : true;
+ }
+ constexpr operator bool() const noexcept {
+ return m_val ? true : false;
+ }
+};
+
+struct HiLoLongLong {
+private:
+ ULong m_hi;
+ ULong m_lo;
+
+public:
+ constexpr HiLoLongLong() noexcept
+ : m_hi(0)
+ , m_lo(0) {
+ }
+ constexpr HiLoLongLong(LongLong val) noexcept
+ : m_hi(static_cast<ULong>((static_cast<ULongLong>(val) & 0xffffffff00000000ull) >> 32))
+ , m_lo(static_cast<ULong>((static_cast<ULongLong>(val) & 0x00000000ffffffffull) >> 0)) {
+ }
+ constexpr operator LongLong() const noexcept {
+ return static_cast<LongLong>((static_cast<ULongLong>(m_hi) << 32) | (static_cast<ULongLong>(m_lo) << 0));
+ }
+};
+
+using ResultBool = ULong;
+
+template <std::size_t size>
+struct CharBuf {
+private:
+ Char buf[size] = "";
+
+public:
+ CharBuf() = default;
+ CharBuf(const CharBuf &) = default;
+ CharBuf(CharBuf &&) = default;
+ CharBuf & operator=(const CharBuf &) = default;
+ CharBuf & operator=(CharBuf &&) = default;
+
+public:
+ constexpr CharBuf(std::nullptr_t) noexcept
+ : CharBuf() {
+ }
+ inline CharBuf(const char * str) noexcept
+ : CharBuf() {
+ if (str) {
+ std::copy(str, str + std::min(std::strlen(str), size - 1), buf);
+ std::fill(buf + std::min(std::strlen(str), size - 1), buf + size, Char('\0'));
+ }
+ }
+ inline CharBuf(const std::string_view & str) noexcept
+ : CharBuf() {
+ std::copy(str.data(), str.data() + std::min(str.length(), size - 1), buf);
+ std::fill(buf + std::min(str.length(), size - 1), buf + size, Char('\0'));
+ }
+ inline CharBuf(const std::string & str) noexcept
+ : CharBuf() {
+ std::copy(str.data(), str.data() + std::min(str.length(), size - 1), buf);
+ std::fill(buf + std::min(str.length(), size - 1), buf + size, Char('\0'));
+ }
+ inline CharBuf & operator=(std::nullptr_t) noexcept {
+ std::fill(buf, buf + size, Char('\0'));
+ return *this;
+ }
+ inline CharBuf & operator=(const char * str) noexcept {
+ if (str) {
+ std::copy(str, str + std::min(std::strlen(str), size - 1), buf);
+ std::fill(buf + std::min(std::strlen(str), size - 1), buf + size, Char('\0'));
+ } else {
+ std::fill(buf, buf + size, Char('\0'));
+ }
+ return *this;
+ }
+ inline CharBuf & operator=(const std::string & str) noexcept {
+ std::fill(buf, buf + size, Char('\0'));
+ std::copy(str.data(), str.data() + std::min(str.length(), size - 1), buf);
+ std::fill(buf + std::min(str.length(), size - 1), buf + size, Char('\0'));
+ return *this;
+ }
+ inline CharBuf & operator=(const std::string_view & str) noexcept {
+ std::fill(buf, buf + size, Char('\0'));
+ std::copy(str.data(), str.data() + std::min(str.length(), size - 1), buf);
+ std::fill(buf + std::min(str.length(), size - 1), buf + size, Char('\0'));
+ return *this;
+ }
+ inline explicit operator std::string_view() const noexcept {
+ std::size_t len = std::find(buf, buf + size - 1, Char('\0')) - buf;
+ return std::string_view(buf, buf + len);
+ }
+ inline operator std::string() const {
+ std::size_t len = std::find(buf, buf + size - 1, Char('\0')) - buf;
+ return std::string(buf, buf + len);
+ }
+};
+
+inline constexpr std::size_t SizeOfChar = sizeof(Char);
+inline constexpr std::size_t SizeOfByte = sizeof(Byte);
+inline constexpr std::size_t SizeOfBool = sizeof(Bool);
+inline constexpr std::size_t SizeOfLong = sizeof(Long);
+inline constexpr std::size_t SizeOfLongLong = sizeof(LongLong);
+inline constexpr std::size_t SizeOfDouble = sizeof(Double);
+inline constexpr std::size_t SizeOfHiLoLongLong = sizeof(HiLoLongLong);
+
+static_assert(SizeOfChar == 1);
+static_assert(SizeOfByte == 1);
+
+static_assert(SizeOfBool == SizeOfLong);
+
+static_assert(SizeOfHiLoLongLong == SizeOfLongLong);
+
+static_assert(SizeOfLongLong == 8);
+
+static_assert(sizeof(Padding1) == 1);
+
+static_assert(sizeof(PaddingLong) == SizeOfLong);
+
+static_assert(sizeof(CharBuf<1>) == 1);
+
+
+
+} // namespace ASIO_VERSION_NAMESPACE
+
+
+
+} // namespace Core
+
+
+
+} // namespace ASIO
+
+
+
+#endif // ASIO_ASIOCONFIG_HPP
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOCore.hpp b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOCore.hpp
new file mode 100644
index 00000000..97b6206a
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOCore.hpp
@@ -0,0 +1,469 @@
+
+#ifndef ASIO_ASIOCORE_HPP
+#define ASIO_ASIOCORE_HPP
+
+
+
+#include "ASIOVersion.hpp"
+#include "ASIOConfig.hpp"
+
+#include <algorithm>
+#include <string>
+#include <type_traits>
+
+#include <cstddef>
+#include <cstdint>
+
+
+
+namespace ASIO {
+
+
+
+inline namespace Core {
+
+
+
+inline namespace ASIO_VERSION_NAMESPACE {
+
+
+
+using Samples = HiLoLongLong;
+
+using TimeStamp = HiLoLongLong;
+
+using SampleRate = Double;
+
+enum class SampleType : Long {
+ Int16MSB = 0,
+ Int24MSB = 1,
+ Int32MSB = 2,
+ Float32MSB = 3,
+ Float64MSB = 4,
+ Int32MSB16 = 8,
+ Int32MSB18 = 9,
+ Int32MSB20 = 10,
+ Int32MSB24 = 11,
+ Int16LSB = 16,
+ Int24LSB = 17,
+ Int32LSB = 18,
+ Float32LSB = 19,
+ Float64LSB = 20,
+ Int32LSB16 = 24,
+ Int32LSB18 = 25,
+ Int32LSB20 = 26,
+ Int32LSB24 = 27,
+ DSDInt8LSB1 = 32,
+ DSDInt8MSB1 = 33,
+ DSDInt8NER8 = 40,
+};
+static_assert(sizeof(SampleType) == SizeOfLong);
+
+enum class ErrorCode : Long {
+ OK = 0,
+ SUCCESS = 0x3f4847a0,
+ NotPresent = -1000,
+ HWMalfunction = -999,
+ InvalidParameter = -998,
+ InvalidMode = -997,
+ SPNotAdvancing = -996,
+ NoClock = -995,
+ NoMemory = -994,
+};
+static_assert(sizeof(ErrorCode) == SizeOfLong);
+
+enum TimeCodeFlags : ULong {
+ TimeCodeFlagValid = 1 << 0,
+ TimeCodeFlagRunning = 1 << 1,
+ TimeCodeFlagReverse = 1 << 2,
+ TimeCodeFlagOnspeed = 1 << 3,
+ TimeCodeFlagStill = 1 << 4,
+ TimeCodeFlagSpeedValid = 1 << 8,
+};
+constexpr inline TimeCodeFlags operator|(TimeCodeFlags a, TimeCodeFlags b) noexcept {
+ return static_cast<TimeCodeFlags>(static_cast<std::underlying_type<TimeCodeFlags>::type>(a) | static_cast<std::underlying_type<TimeCodeFlags>::type>(b));
+}
+constexpr inline TimeCodeFlags operator&(TimeCodeFlags a, TimeCodeFlags b) noexcept {
+ return static_cast<TimeCodeFlags>(static_cast<std::underlying_type<TimeCodeFlags>::type>(a) & static_cast<std::underlying_type<TimeCodeFlags>::type>(b));
+}
+constexpr inline TimeCodeFlags operator^(TimeCodeFlags a, TimeCodeFlags b) noexcept {
+ return static_cast<TimeCodeFlags>(static_cast<std::underlying_type<TimeCodeFlags>::type>(a) ^ static_cast<std::underlying_type<TimeCodeFlags>::type>(b));
+}
+constexpr inline TimeCodeFlags operator~(TimeCodeFlags a) noexcept {
+ return static_cast<TimeCodeFlags>(~static_cast<std::underlying_type<TimeCodeFlags>::type>(a));
+}
+constexpr inline TimeCodeFlags & operator|=(TimeCodeFlags & a, TimeCodeFlags b) noexcept {
+ return a = a | b;
+}
+constexpr inline TimeCodeFlags & operator&=(TimeCodeFlags & a, TimeCodeFlags b) noexcept {
+ return a = a & b;
+}
+constexpr inline TimeCodeFlags & operator^=(TimeCodeFlags & a, TimeCodeFlags b) noexcept {
+ return a = a ^ b;
+}
+static_assert(sizeof(TimeCodeFlags) == SizeOfLong);
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct TimeCode {
+ Double speed = 0.0;
+ HiLoLongLong timeCodeSamples = 0;
+ TimeCodeFlags flags = static_cast<TimeCodeFlags>(0);
+ Padding1 future[64] = {0};
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(TimeCode) == (SizeOfDouble + SizeOfLongLong + SizeOfLong + 64));
+
+enum TimeInfoFlags : ULong {
+ TimeInfoFlagSystemTimeValid = 1 << 0,
+ TimeInfoFlagSamplePositionValid = 1 << 1,
+ TimeInfoFlagSampleRateValid = 1 << 2,
+ TimeInfoFlagSpeedValid = 1 << 3,
+ TimeInfoFlagSampleRateChanged = 1 << 4,
+ TimeInfoFlagClockSourceChanged = 1 << 5,
+};
+constexpr inline TimeInfoFlags operator|(TimeInfoFlags a, TimeInfoFlags b) noexcept {
+ return static_cast<TimeInfoFlags>(static_cast<std::underlying_type<TimeInfoFlags>::type>(a) | static_cast<std::underlying_type<TimeInfoFlags>::type>(b));
+}
+constexpr inline TimeInfoFlags operator&(TimeInfoFlags a, TimeInfoFlags b) noexcept {
+ return static_cast<TimeInfoFlags>(static_cast<std::underlying_type<TimeInfoFlags>::type>(a) & static_cast<std::underlying_type<TimeInfoFlags>::type>(b));
+}
+constexpr inline TimeInfoFlags operator^(TimeInfoFlags a, TimeInfoFlags b) noexcept {
+ return static_cast<TimeInfoFlags>(static_cast<std::underlying_type<TimeInfoFlags>::type>(a) ^ static_cast<std::underlying_type<TimeInfoFlags>::type>(b));
+}
+constexpr inline TimeInfoFlags operator~(TimeInfoFlags a) noexcept {
+ return static_cast<TimeInfoFlags>(~static_cast<std::underlying_type<TimeInfoFlags>::type>(a));
+}
+constexpr inline TimeInfoFlags & operator|=(TimeInfoFlags & a, TimeInfoFlags b) noexcept {
+ return a = a | b;
+}
+constexpr inline TimeInfoFlags & operator&=(TimeInfoFlags & a, TimeInfoFlags b) noexcept {
+ return a = a & b;
+}
+constexpr inline TimeInfoFlags & operator^=(TimeInfoFlags & a, TimeInfoFlags b) noexcept {
+ return a = a ^ b;
+}
+static_assert(sizeof(TimeInfoFlags) == SizeOfLong);
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct TimeInfo {
+ Double speed = 0.0;
+ HiLoLongLong systemTime = 0;
+ HiLoLongLong samplePosition = 0;
+ SampleRate sampleRate = 0.0;
+ TimeInfoFlags flags = static_cast<TimeInfoFlags>(0);
+ Padding1 reserved[12] = {0};
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(TimeInfo) == (SizeOfDouble + SizeOfLongLong + SizeOfLongLong + SizeOfDouble + SizeOfLong + 12));
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct Time {
+ PaddingLong reserved[4] = {0};
+ TimeInfo timeInfo;
+ TimeCode timeCode;
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(Time) == (4 * SizeOfLong + sizeof(TimeInfo) + sizeof(TimeCode)));
+
+enum class MessageSelector : Long {
+ SelectorSupported = 1,
+ EngineVersion = 2,
+ ResetRequest = 3,
+ BufferSizeChange = 4,
+ ResyncRequest = 5,
+ LatenciesChanged = 6,
+ SupportsTimeInfo = 7,
+ SupportsTimeCode = 8,
+ MMCCommand = 9,
+ SupportsInputMonitor = 10,
+ SupportsInputGain = 11,
+ SupportsInputMeter = 12,
+ SupportsOutputGain = 13,
+ SupportsOutputMeter = 14,
+ Overload = 15,
+};
+static_assert(sizeof(MessageSelector) == SizeOfLong);
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#if ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+#pragma push_macro("cdecl")
+#ifdef cdecl
+#undef cdecl
+#endif
+#endif // ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+struct Callbacks {
+ void(ASIO_CALL * bufferSwitch ASIO_ATTR_CALL)(Long doubleBufferIndex, Bool directProcess) noexcept = nullptr;
+ void(ASIO_CALL * sampleRateDidChange ASIO_ATTR_CALL)(SampleRate sRate) noexcept = nullptr;
+ Long(ASIO_CALL * asioMessage ASIO_ATTR_CALL)(MessageSelector selector, Long value, void const * message, Double const * opt) noexcept = nullptr;
+ Time const *(ASIO_CALL * bufferSwitchTimeInfo ASIO_ATTR_CALL)(Time const * params, Long doubleBufferIndex, Bool directProcess) noexcept = nullptr;
+};
+#if ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+#pragma pop_macro("cdecl")
+#endif // ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(Callbacks) == (4 * sizeof(void (*)(void))));
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct ClockSource {
+ Long index = 0;
+ Long associatedChannel = 0;
+ Long associatedGroup = 0;
+ Bool isCurrentSource = false;
+ CharBuf<32> name = nullptr;
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(ClockSource) == (SizeOfLong + SizeOfLong + SizeOfLong + SizeOfBool + 32));
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct ChannelInfo {
+ Long channel = 0;
+ Bool isInput = false;
+ Bool isActive = false;
+ Long channelGroup = 0;
+ SampleType type = static_cast<SampleType>(0);
+ CharBuf<32> name = nullptr;
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(ChannelInfo) == (SizeOfLong + SizeOfBool + SizeOfBool + SizeOfLong + sizeof(SampleType) + 32));
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct BufferInfo {
+ Bool isInput = false;
+ Long channelNum = 0;
+ void * buffers[2] = {nullptr, nullptr};
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(BufferInfo) == (SizeOfBool + SizeOfLong + 2 * sizeof(void *)));
+
+enum class FutureSelector : Long {
+ EnableTimeCodeRead = 1,
+ DisableTimeCodeRead = 2,
+ SetInputMonitor = 3,
+ Transport = 4,
+ SetInputGain = 5,
+ GetInputMeter = 6,
+ SetOutputGain = 7,
+ GetOutputMeter = 8,
+ CanInputMonitor = 9,
+ CanTimeInfo = 10,
+ CanTimeCode = 11,
+ CanTransport = 12,
+ CanInputGain = 13,
+ CanInputMeter = 14,
+ CanOutputGain = 15,
+ CanOutputMeter = 16,
+ OptionalOne = 17,
+ SetIoFormat = 0x23111961,
+ GetIoFormat = 0x23111983,
+ CanDoIoFormat = 0x23112004,
+ CanReportOverload = 0x24042012,
+ GetInternalBufferSamples = 0x25042012,
+};
+static_assert(sizeof(FutureSelector) == SizeOfLong);
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct InputMonitor {
+ Long input = 0;
+ Long output = 0;
+ Long gain = 0;
+ Bool state = false;
+ Long pan = 0;
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(InputMonitor) == (SizeOfLong + SizeOfLong + SizeOfLong + SizeOfBool + SizeOfLong));
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct ChannelControls {
+ Long channel = 0;
+ Bool isInput = false;
+ Long gain = 0;
+ Long meter = 0;
+ Padding1 future[32] = {0};
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(ChannelControls) == (SizeOfLong + SizeOfBool + SizeOfLong + SizeOfLong + 32));
+
+enum class TransportCommand : Long {
+ Start = 1,
+ Stop = 2,
+ Locate = 3,
+ PunchIn = 4,
+ PunchOut = 5,
+ ArmOn = 6,
+ ArmOff = 7,
+ MonitorOn = 8,
+ MonitorOff = 9,
+ Arm = 10,
+ Monitor = 11,
+};
+static_assert(sizeof(TransportCommand) == SizeOfLong);
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct TransportParameters {
+ TransportCommand command = static_cast<TransportCommand>(0);
+ HiLoLongLong samplePosition = 0;
+ Long track = 0;
+ Byte trackSwitches[64] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ Padding1 future[64] = {0};
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(TransportParameters) == (sizeof(TransportCommand) + SizeOfLongLong + SizeOfLong + 64 + 64));
+
+enum class IoFormatType : Long {
+ Invalid = -1,
+ PCM = 0,
+ DSD = 1,
+};
+static_assert(sizeof(IoFormatType) == SizeOfLong);
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct IoFormat {
+ IoFormatType FormatType = static_cast<IoFormatType>(0);
+ Padding1 future[512 - sizeof(IoFormatType)] = {0};
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(IoFormat) == 512);
+
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(push, 4)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+struct InternalBufferInfo {
+ Long inputSamples = 0;
+ Long outputSamples = 0;
+};
+#if ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif // ASIO_SYSTEM_WINDOWS && ASIO_HAVE_PRAGMA_PACK
+static_assert(sizeof(InternalBufferInfo) == (SizeOfLong + SizeOfLong));
+
+
+
+typedef ASIO_INTERFACE ISystemDriver ISystemDriver;
+
+using DriverName = CharBuf<32>;
+using ErrorMessage = CharBuf<124>;
+
+#if ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+#pragma push_macro("thiscall")
+#ifdef thiscall
+#undef thiscall
+#endif
+#endif // ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+ASIO_INTERFACE ISystemDriver : public IUnknown {
+ [[nodiscard]] virtual ResultBool ASIO_DRIVERCALL init ASIO_ATTR_DRIVERCALL(SysHandle sysHandle) = 0;
+ virtual void ASIO_DRIVERCALL getDriverName ASIO_ATTR_DRIVERCALL(DriverName * name) = 0;
+ [[nodiscard]] virtual Long ASIO_DRIVERCALL getDriverVersion ASIO_ATTR_DRIVERCALL() = 0;
+ virtual void ASIO_DRIVERCALL getErrorMessage ASIO_ATTR_DRIVERCALL(ErrorMessage * string) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL start ASIO_ATTR_DRIVERCALL() = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL stop ASIO_ATTR_DRIVERCALL() = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL getChannels ASIO_ATTR_DRIVERCALL(Long * numInputChannels, Long * numOutputChannels) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL getLatencies ASIO_ATTR_DRIVERCALL(Long * inputLatency, Long * outputLatency) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL getBufferSize ASIO_ATTR_DRIVERCALL(Long * minSize, Long * maxSize, Long * preferredSize, Long * granularity) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL canSampleRate ASIO_ATTR_DRIVERCALL(SampleRate sampleRate) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL getSampleRate ASIO_ATTR_DRIVERCALL(SampleRate * sampleRate) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL setSampleRate ASIO_ATTR_DRIVERCALL(SampleRate sampleRate) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL getClockSources ASIO_ATTR_DRIVERCALL(ClockSource * clocks, Long * numSources) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL setClockSource ASIO_ATTR_DRIVERCALL(Long reference) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL getSamplePosition ASIO_ATTR_DRIVERCALL(HiLoLongLong * samplePosition, HiLoLongLong * timeStamp) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL getChannelInfo ASIO_ATTR_DRIVERCALL(ChannelInfo * info) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL createBuffers ASIO_ATTR_DRIVERCALL(BufferInfo * bufferInfos, Long numChannels, Long bufferSize, Callbacks const * callbacks) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL disposeBuffers ASIO_ATTR_DRIVERCALL() = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL controlPanel ASIO_ATTR_DRIVERCALL() = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL future ASIO_ATTR_DRIVERCALL(FutureSelector selector, void * opt) = 0;
+ [[nodiscard]] virtual ErrorCode ASIO_DRIVERCALL outputReady ASIO_ATTR_DRIVERCALL() = 0;
+};
+#if ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+#pragma pop_macro("thiscall")
+#endif // ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+
+
+
+class IDriver {
+protected:
+ IDriver() = default;
+
+public:
+ virtual ~IDriver() noexcept(false) { }
+
+public:
+ virtual void getDriverName(DriverName * name) = 0;
+ [[nodiscard]] virtual Long getDriverVersion() = 0;
+ virtual void getErrorMessage(ErrorMessage * string) = 0;
+ [[nodiscard]] virtual ErrorCode start() = 0;
+ [[nodiscard]] virtual ErrorCode stop() = 0;
+ [[nodiscard]] virtual ErrorCode getChannels(Long * numInputChannels, Long * numOutputChannels) = 0;
+ [[nodiscard]] virtual ErrorCode getLatencies(Long * inputLatency, Long * outputLatency) = 0;
+ [[nodiscard]] virtual ErrorCode getBufferSize(Long * minSize, Long * maxSize, Long * preferredSize, Long * granularity) = 0;
+ [[nodiscard]] virtual ErrorCode canSampleRate(SampleRate sampleRate) = 0;
+ [[nodiscard]] virtual ErrorCode getSampleRate(SampleRate * sampleRate) = 0;
+ [[nodiscard]] virtual ErrorCode setSampleRate(SampleRate sampleRate) = 0;
+ [[nodiscard]] virtual ErrorCode getClockSources(ClockSource * clocks, Long * numSources) = 0;
+ [[nodiscard]] virtual ErrorCode setClockSource(Long reference) = 0;
+ [[nodiscard]] virtual ErrorCode getSamplePosition(HiLoLongLong * samplePosition, HiLoLongLong * timeStamp) = 0;
+ [[nodiscard]] virtual ErrorCode getChannelInfo(ChannelInfo * info) = 0;
+ [[nodiscard]] virtual ErrorCode createBuffers(BufferInfo * bufferInfos, Long numChannels, Long bufferSize, Callbacks const * callbacks) = 0;
+ [[nodiscard]] virtual ErrorCode disposeBuffers() = 0;
+ [[nodiscard]] virtual ErrorCode controlPanel() = 0;
+ [[nodiscard]] virtual ErrorCode future(FutureSelector selector, void * opt) = 0;
+ [[nodiscard]] virtual ErrorCode outputReady() = 0;
+};
+
+
+
+} // namespace ASIO_VERSION_NAMESPACE
+
+
+
+} // namespace Core
+
+
+
+} // namespace ASIO
+
+
+
+#endif // ASIO_ASIOCORE_HPP
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOModern.hpp b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOModern.hpp
new file mode 100644
index 00000000..0413bed2
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOModern.hpp
@@ -0,0 +1,960 @@
+
+#ifndef ASIO_ASIOMODERN_HPP
+#define ASIO_ASIOMODERN_HPP
+
+
+
+#include "ASIOVersion.hpp"
+#include "ASIOConfig.hpp"
+#include "ASIOCore.hpp"
+
+#include <array>
+#include <exception>
+#include <mutex>
+#include <stdexcept>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+
+
+
+namespace ASIO {
+
+
+
+inline namespace Modern {
+
+
+
+inline namespace ASIO_VERSION_NAMESPACE {
+
+
+
+class Error
+ : public std::runtime_error {
+private:
+ ErrorCode m_Code;
+
+private:
+ static constexpr std::string_view Message(ErrorCode ec) noexcept {
+ std::string_view message = "";
+ switch (ec) {
+ case ErrorCode::OK:
+ message = "OK";
+ break;
+ case ErrorCode::SUCCESS:
+ message = "SUCCESS";
+ break;
+ case ErrorCode::NotPresent:
+ message = "NotPresent";
+ break;
+ case ErrorCode::HWMalfunction:
+ message = "HWMalfunction";
+ break;
+ case ErrorCode::InvalidParameter:
+ message = "InvalidParameter";
+ break;
+ case ErrorCode::InvalidMode:
+ message = "InvalidMode";
+ break;
+ case ErrorCode::SPNotAdvancing:
+ message = "SPNotAdvancing";
+ break;
+ case ErrorCode::NoClock:
+ message = "NoClock";
+ break;
+ case ErrorCode::NoMemory:
+ message = "NoMemory";
+ break;
+ default:
+ message = "";
+ break;
+ }
+ return message;
+ }
+
+public:
+ Error(ErrorCode ec)
+ : std::runtime_error(std::string("ASIO Error ") + std::string(Message(ec)))
+ , m_Code(ec) {
+ return;
+ }
+ ErrorCode Code() const noexcept {
+ return m_Code;
+ }
+};
+
+
+
+struct CallbacksWithContext {
+ void (*bufferSwitch)(void * context, Long doubleBufferIndex, Bool directProcess) noexcept = nullptr;
+ void (*sampleRateDidChange)(void * context, SampleRate sRate) noexcept = nullptr;
+ Long (*asioMessage)(void * context, MessageSelector selector, const Long value, const void * message, const Double * opt) noexcept = nullptr;
+ const Time * (*bufferSwitchTimeInfo)(void * context, const Time * params, Long doubleBufferIndex, Bool directProcess) noexcept = nullptr;
+};
+
+
+struct CallbacksWrapperState {
+ CallbacksWithContext callbacks;
+ void * context = nullptr;
+};
+
+
+#if ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+#pragma push_macro("cdecl")
+#ifdef cdecl
+#undef cdecl
+#endif
+#endif // ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+template <typename Tarray, Tarray * A, std::size_t I>
+class CallbacksWrapper {
+public:
+ static constexpr Callbacks init() noexcept {
+ Callbacks result = {&CallbackBufferSwitch, &CallbackSampleRateDidChange, &CallbackAsioMessage, &CallbackBufferSwitchTimeInfo};
+ return result;
+ }
+
+public:
+ static void ASIO_CALL CallbackBufferSwitch ASIO_ATTR_CALL(Long doubleBufferIndex, Bool directProcess) noexcept {
+ return (*A)[I].callbacks.bufferSwitch((*A)[I].context, doubleBufferIndex, directProcess);
+ }
+ static void ASIO_CALL CallbackSampleRateDidChange ASIO_ATTR_CALL(SampleRate sRate) noexcept {
+ return (*A)[I].callbacks.sampleRateDidChange((*A)[I].context, sRate);
+ }
+ static Long ASIO_CALL CallbackAsioMessage ASIO_ATTR_CALL(MessageSelector selector, Long value, const void * message, const Double * opt) noexcept {
+ return (*A)[I].callbacks.asioMessage((*A)[I].context, selector, value, message, opt);
+ }
+ static const Time * ASIO_CALL CallbackBufferSwitchTimeInfo ASIO_ATTR_CALL(const Time * params, Long doubleBufferIndex, Bool directProcess) noexcept {
+ return (*A)[I].callbacks.bufferSwitchTimeInfo((*A)[I].context, params, doubleBufferIndex, directProcess);
+ }
+};
+#if ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+#pragma pop_macro("cdecl")
+#endif // ASIO_SYSTEM_WINDOWS && (ASIO_COMPILER_GCC || ASIO_COMPILER_CLANG)
+
+
+namespace detail {
+
+template <typename T, std::size_t N, typename Tx>
+constexpr std::array<T, N> init_array(const Tx & x) {
+ std::array<T, N> result{};
+ for (std::size_t i = 0; i < N; ++i) {
+ result[i] = x;
+ }
+ return result;
+}
+
+} // namespace detail
+
+
+template <std::uint64_t AppID1, std::uint64_t AppID2, std::size_t MaxInstances>
+class AsioCallbacksMultiplexerGlobalState {
+private:
+ template <typename Tarray, Tarray * a, std::size_t... Is>
+ static constexpr auto construct_callbacks_array(std::index_sequence<Is...>) noexcept -> std::array<Callbacks, sizeof...(Is)> {
+ return {CallbacksWrapper<Tarray, a, Is>::init()...};
+ }
+
+private:
+ static inline std::mutex s_AllocationMutex;
+ static inline std::array<bool, MaxInstances> s_Allocation = detail::init_array<bool, MaxInstances>(false);
+ static inline std::array<CallbacksWrapperState, MaxInstances> s_AsioCallbackWrapperStates = detail::init_array<CallbacksWrapperState, MaxInstances>(CallbacksWrapperState{
+ {nullptr, nullptr, nullptr, nullptr},
+ nullptr
+ });
+ static constexpr inline std::array<Callbacks, MaxInstances> s_AsioCallbacks = construct_callbacks_array<std::array<CallbacksWrapperState, MaxInstances>, &s_AsioCallbackWrapperStates>(std::make_index_sequence<MaxInstances>());
+
+private:
+ static std::size_t Alloc() {
+ std::lock_guard<std::mutex> guard(s_AllocationMutex);
+ for (std::size_t i = 0; i < MaxInstances; ++i) {
+ if (!s_Allocation[i]) {
+ s_Allocation[i] = true;
+ return i;
+ }
+ }
+ throw Error(ErrorCode::NoMemory);
+ }
+ static void Free(std::size_t index) noexcept {
+ std::lock_guard<std::mutex> guard(s_AllocationMutex);
+ assert(s_Allocation[index]);
+ s_Allocation[index] = false;
+ }
+
+public:
+ static std::pair<std::size_t, Callbacks> Multiplex(void * context, CallbacksWithContext callbacks) {
+ std::size_t cookie = Alloc();
+ s_AsioCallbackWrapperStates[cookie] = {callbacks, context};
+ return std::make_pair(cookie, s_AsioCallbacks[cookie]);
+ }
+ static void Unmultiplex(std::pair<std::size_t, Callbacks> state) noexcept {
+ Free(state.first);
+ }
+};
+
+
+class IMultiplexedCallbacks {
+protected:
+ IMultiplexedCallbacks() = default;
+
+public:
+ IMultiplexedCallbacks(const IMultiplexedCallbacks &) = delete;
+ IMultiplexedCallbacks & operator=(const IMultiplexedCallbacks &) = delete;
+
+public:
+ virtual ~IMultiplexedCallbacks() = default;
+
+public:
+ virtual operator const Callbacks *() const noexcept = 0;
+ virtual operator const Callbacks &() const noexcept = 0;
+ virtual operator Callbacks *() noexcept = 0;
+ virtual operator Callbacks &() noexcept = 0;
+};
+
+
+template <std::uint64_t AppID1, std::uint64_t AppID2, std::size_t MaxInstances>
+class MultiplexedCallbacks
+ : public IMultiplexedCallbacks {
+public:
+ using GlobalState = AsioCallbacksMultiplexerGlobalState<AppID1, AppID2, MaxInstances>;
+ using State = std::unique_ptr<IMultiplexedCallbacks>;
+
+private:
+ std::pair<std::size_t, Callbacks> m_State;
+
+public:
+ MultiplexedCallbacks(void * context, CallbacksWithContext callbacks)
+ : m_State(GlobalState::Multiplex(context, callbacks)) {
+ if (!callbacks.bufferSwitch) {
+ m_State.second.bufferSwitch = nullptr;
+ }
+ if (!callbacks.sampleRateDidChange) {
+ m_State.second.sampleRateDidChange = nullptr;
+ }
+ if (!callbacks.asioMessage) {
+ m_State.second.asioMessage = nullptr;
+ }
+ if (!callbacks.bufferSwitchTimeInfo) {
+ m_State.second.bufferSwitchTimeInfo = nullptr;
+ }
+ }
+ MultiplexedCallbacks(const MultiplexedCallbacks &) = delete;
+ MultiplexedCallbacks & operator=(const MultiplexedCallbacks &) = delete;
+ ~MultiplexedCallbacks() final {
+ GlobalState::Unmultiplex(m_State);
+ }
+
+public:
+ operator const Callbacks *() const noexcept final {
+ return &m_State.second;
+ }
+ operator const Callbacks &() const noexcept final {
+ return m_State.second;
+ }
+ operator Callbacks *() noexcept final {
+ return &m_State.second;
+ }
+ operator Callbacks &() noexcept final {
+ return m_State.second;
+ }
+
+public:
+ static std::unique_ptr<MultiplexedCallbacks> make(void * context, CallbacksWithContext callbacks) {
+ return std::make_unique<MultiplexedCallbacks>(context, callbacks);
+ }
+ static std::unique_ptr<MultiplexedCallbacks> null() {
+ return std::unique_ptr<MultiplexedCallbacks>();
+ }
+};
+
+
+
+struct Channels {
+ Long Input = 0;
+ Long Output = 0;
+};
+
+struct Latencies {
+ Long Input = 0;
+ Long Output = 0;
+};
+
+struct BufferSizes {
+ Long Min = 0;
+ Long Max = 0;
+ Long Preferred = 0;
+ Long Granularity = 0;
+};
+
+struct SamplePosition {
+ Samples samplePosition = 0;
+ TimeStamp systemTime = 0;
+};
+
+struct BufferIndex {
+ std::uint8_t Index : 1;
+ constexpr BufferIndex() noexcept
+ : Index(0) {
+ }
+ constexpr BufferIndex(Long doubleBufferIndex) noexcept
+ : Index(static_cast<std::uint8_t>(static_cast<ULong>(doubleBufferIndex) & 1u)) {
+ }
+ constexpr BufferIndex(std::size_t bufferIndex) noexcept
+ : Index(static_cast<std::uint8_t>(bufferIndex & 1u)) {
+ }
+ constexpr operator std::size_t() const noexcept {
+ return Index;
+ }
+};
+
+class Driver {
+
+public:
+ class ICallbackHandler {
+ protected:
+ ICallbackHandler() = default;
+
+ public:
+ ICallbackHandler(const ICallbackHandler &) = delete;
+ ICallbackHandler & operator=(const ICallbackHandler &) = delete;
+ virtual ~ICallbackHandler() = default;
+
+ public:
+ virtual Long CallbackMessage(Driver & driver, MessageSelector selector, Long value, const void * message, const Double * opt) noexcept = 0;
+ virtual void CallbackSampleRateDidChange(Driver & driver, SampleRate sRate) noexcept = 0;
+ virtual void CallbackBufferSwitch(Driver & driver, Long doubleBufferIndex, Bool directProcess) noexcept = 0;
+ virtual const Time * CallbackBufferSwitchTimeInfo(Driver & driver, const Time * params, Long doubleBufferIndex, Bool directProcess) noexcept = 0;
+ };
+
+ class CallbackHandler
+ : public ICallbackHandler {
+ /*
+ void MessageResetRequest() noexcept override;
+ bool MessageBufferSizeChange(ASIO::Long newSize) noexcept override;
+ bool MessageResyncRequest() noexcept override;
+ void MessageLatenciesChanged() noexcept override;
+ ASIO::Long MessageMMCCommand(ASIO::Long value, const void * message, const ASIO::Double * opt) noexcept override;
+ void MessageOverload() noexcept override;
+ ASIO::Long MessageUnknown(ASIO::MessageSelector selector, ASIO::Long value, const void * message, const ASIO::Double * opt) noexcept override;
+ void RealtimeSampleRateDidChange(ASIO::SampleRate sRate) noexcept override;
+ void RealtimeRequestDeferredProcessing(bool value) noexcept override;
+ void RealtimeTimeInfo(ASIO::Time time) noexcept override;
+ void RealtimeBufferSwitch(ASIO::BufferIndex bufferIndex) noexcept override;
+ */
+ public:
+ CallbackHandler() = default;
+ CallbackHandler(const CallbackHandler &) = delete;
+ CallbackHandler & operator=(const CallbackHandler &) = delete;
+ virtual ~CallbackHandler() = default;
+
+ public:
+ bool MessageSelectorSupported(MessageSelector selector) const noexcept {
+ bool result = false;
+ switch (selector) {
+ case MessageSelector::SelectorSupported:
+ result = true;
+ break;
+ case MessageSelector::EngineVersion:
+ result = true;
+ break;
+ case MessageSelector::ResetRequest:
+ result = true;
+ break;
+ case MessageSelector::BufferSizeChange:
+ result = true;
+ break;
+ case MessageSelector::ResyncRequest:
+ result = true;
+ break;
+ case MessageSelector::LatenciesChanged:
+ result = true;
+ break;
+ case MessageSelector::SupportsTimeInfo:
+ result = true;
+ break;
+ case MessageSelector::SupportsTimeCode:
+ result = true;
+ break;
+ case MessageSelector::MMCCommand:
+ result = true;
+ break;
+ case MessageSelector::SupportsInputMonitor:
+ result = true;
+ break;
+ case MessageSelector::SupportsInputGain:
+ result = true;
+ break;
+ case MessageSelector::SupportsInputMeter:
+ result = true;
+ break;
+ case MessageSelector::SupportsOutputGain:
+ result = true;
+ break;
+ case MessageSelector::SupportsOutputMeter:
+ result = true;
+ break;
+ case MessageSelector::Overload:
+ result = true;
+ break;
+ }
+ return result;
+ }
+ Long MessageEngineVersion() const noexcept {
+ return 2;
+ }
+ virtual void MessageResetRequest() noexcept = 0;
+ virtual bool MessageBufferSizeChange(Long newSize) noexcept {
+ static_cast<void>(newSize);
+ return false;
+ }
+ virtual bool MessageResyncRequest() noexcept {
+ return false;
+ }
+ virtual void MessageLatenciesChanged() noexcept {
+ return;
+ }
+ bool MessageSupportsTimeInfo() const noexcept {
+ return true;
+ }
+ bool MessageSupportsTimeCode() const noexcept {
+ return true;
+ }
+ virtual Long MessageMMCCommand(Long value, const void * message, const Double * opt) noexcept {
+ static_cast<void>(value);
+ static_cast<void>(message);
+ static_cast<void>(opt);
+ return 0;
+ }
+ bool MessageSupportsInputMonitor() const noexcept {
+ return true;
+ }
+ bool MessageSupportsInputGain() const noexcept {
+ return true;
+ }
+ bool MessageSupportsInputMeter() const noexcept {
+ return true;
+ }
+ bool MessageSupportsOutputGain() const noexcept {
+ return true;
+ }
+ bool MessageSupportsOutputMeter() const noexcept {
+ return true;
+ }
+ virtual void MessageOverload() noexcept {
+ return;
+ }
+ virtual Long MessageUnknown(MessageSelector selector, Long value, const void * message, const Double * opt) noexcept {
+ static_cast<void>(selector);
+ static_cast<void>(value);
+ static_cast<void>(message);
+ static_cast<void>(opt);
+ return 0;
+ }
+ virtual void RealtimeSampleRateDidChange(SampleRate sRate) noexcept {
+ static_cast<void>(sRate);
+ }
+ virtual void RealtimeRequestDeferredProcessing(bool deferred) noexcept {
+ static_cast<void>(deferred);
+ }
+ virtual void RealtimeTimeInfo(Time time) noexcept {
+ static_cast<void>(time);
+ }
+ virtual void RealtimeBufferSwitch(ASIO::BufferIndex bufferIndex) noexcept = 0;
+
+ public:
+ Long CallbackMessage(Driver & driver, MessageSelector selector, Long value, const void * message, const Double * opt) noexcept final {
+ static_cast<void>(driver);
+ Long result = 0;
+ switch (selector) {
+ case MessageSelector::SelectorSupported:
+ result = MessageSelectorSupported(static_cast<MessageSelector>(value)) ? 1 : 0;
+ break;
+ case MessageSelector::EngineVersion:
+ result = MessageEngineVersion();
+ break;
+ case MessageSelector::ResetRequest:
+ MessageResetRequest();
+ result = 1;
+ break;
+ case MessageSelector::BufferSizeChange:
+ result = MessageBufferSizeChange(value) ? 1 : 0;
+ break;
+ case MessageSelector::ResyncRequest:
+ result = MessageResyncRequest() ? 1 : 0;
+ break;
+ case MessageSelector::LatenciesChanged:
+ MessageLatenciesChanged();
+ result = 1;
+ break;
+ case MessageSelector::SupportsTimeInfo:
+ result = MessageSupportsTimeInfo() ? 1 : 0;
+ break;
+ case MessageSelector::SupportsTimeCode:
+ result = MessageSupportsTimeCode() ? 1 : 0;
+ break;
+ case MessageSelector::MMCCommand:
+ result = MessageMMCCommand(value, message, opt);
+ break;
+ case MessageSelector::SupportsInputMonitor:
+ result = MessageSupportsInputMonitor() ? 1 : 0;
+ break;
+ case MessageSelector::SupportsInputGain:
+ result = MessageSupportsInputGain() ? 1 : 0;
+ break;
+ case MessageSelector::SupportsInputMeter:
+ result = MessageSupportsInputMeter() ? 1 : 0;
+ break;
+ case MessageSelector::SupportsOutputGain:
+ result = MessageSupportsOutputGain() ? 1 : 0;
+ break;
+ case MessageSelector::SupportsOutputMeter:
+ result = MessageSupportsOutputMeter() ? 1 : 0;
+ break;
+ case MessageSelector::Overload:
+ MessageOverload();
+ result = 1;
+ break;
+ default:
+ result = MessageUnknown(selector, value, message, opt);
+ break;
+ }
+ return result;
+ }
+ void CallbackSampleRateDidChange(Driver & driver, SampleRate sRate) noexcept final {
+ static_cast<void>(driver);
+ RealtimeSampleRateDidChange(sRate);
+ }
+ void CallbackBufferSwitch(Driver & driver, Long doubleBufferIndex, Bool directProcess) noexcept final {
+ CallbackBufferSwitchTimeInfo(driver, nullptr, doubleBufferIndex, directProcess);
+ }
+ const Time * CallbackBufferSwitchTimeInfo(Driver & driver, const Time * params, Long doubleBufferIndex, Bool directProcess) noexcept final {
+ Time time;
+ if (params) {
+ time = *params;
+ } else {
+ try {
+ HiLoLongLong samplePosition = 0;
+ HiLoLongLong systemTime = 0;
+ if (driver.realDriver().getSamplePosition(&samplePosition, &systemTime) == ErrorCode::OK) {
+ time.timeInfo.flags |= TimeInfoFlagSamplePositionValid | TimeInfoFlagSystemTimeValid;
+ time.timeInfo.samplePosition = samplePosition;
+ time.timeInfo.systemTime = systemTime;
+ time.timeInfo.speed = 1.0;
+ SampleRate sampleRate = 0.0;
+ if (driver.realDriver().getSampleRate(&sampleRate) == ErrorCode::OK) {
+ if (sampleRate >= 0.0) {
+ time.timeInfo.flags |= TimeInfoFlagSampleRateValid;
+ time.timeInfo.sampleRate = sampleRate;
+ }
+ }
+ }
+ } catch (...) {
+ // nothing
+ }
+ }
+ RealtimeRequestDeferredProcessing(!directProcess);
+ RealtimeTimeInfo(time);
+ RealtimeBufferSwitch(doubleBufferIndex);
+ return params;
+ }
+ };
+
+
+private:
+ std::unique_ptr<IDriver> m_Driver;
+
+ ICallbackHandler * m_CallbackHandler = nullptr;
+
+ std::unique_ptr<IMultiplexedCallbacks> m_Callbacks;
+
+private:
+ const IDriver & realDriver() const noexcept {
+ return *m_Driver;
+ }
+ IDriver & realDriver() noexcept {
+ return *m_Driver;
+ }
+
+public:
+ explicit Driver(std::unique_ptr<IDriver> driver)
+ : m_Driver(std::move(driver)) {
+ return;
+ }
+
+ Driver(const Driver &) = delete;
+
+ Driver & operator=(const Driver &) = delete;
+
+ ~Driver() {
+ return;
+ }
+
+private:
+ [[nodiscard]] static ErrorCode CheckResultOutOfMemory(ErrorCode ec) {
+ if (ec == ErrorCode::NoMemory) {
+ throw std::bad_alloc();
+ }
+ return ec;
+ }
+
+ static void CheckResult(ErrorCode expected, ErrorCode ec) {
+ ec = CheckResultOutOfMemory(ec);
+ if (ec != expected) {
+ throw Error(ec);
+ }
+ }
+
+ static void CheckResultNoOutOfMemory(ErrorCode expected, ErrorCode ec) {
+ if (ec != expected) {
+ throw Error(ec);
+ }
+ }
+
+ static void CheckOK(ErrorCode ec) {
+ CheckResult(ErrorCode::OK, ec);
+ }
+
+ static void CheckSUCCESS(ErrorCode ec) {
+ CheckResult(ErrorCode::SUCCESS, ec);
+ }
+
+ static void CheckOKNoOutOfMemory(ErrorCode ec) {
+ CheckResultNoOutOfMemory(ErrorCode::OK, ec);
+ }
+
+ static void CheckSUCCESSNoOutOfMemory(ErrorCode ec) {
+ CheckResultNoOutOfMemory(ErrorCode::SUCCESS, ec);
+ }
+
+private:
+ static Driver * ThisFromVoid(void * context) noexcept {
+ return reinterpret_cast<Driver *>(context);
+ }
+
+ void * MyContext() noexcept {
+ return this;
+ }
+
+ static constexpr CallbacksWithContext MyCallbacks() noexcept {
+ CallbacksWithContext result = {&CallbackBufferSwitch, &CallbackSampleRateDidChange, &CallbackAsioMessage, &CallbackBufferSwitchTimeInfo};
+ return result;
+ }
+
+private:
+ static void CallbackBufferSwitch(void * context, Long doubleBufferIndex, Bool directProcess) noexcept {
+ assert(context);
+ assert(ThisFromVoid(context)->m_CallbackHandler);
+ return ThisFromVoid(context)->m_CallbackHandler->CallbackBufferSwitch(*ThisFromVoid(context), doubleBufferIndex, directProcess);
+ }
+ static void CallbackSampleRateDidChange(void * context, SampleRate sRate) noexcept {
+ assert(context);
+ assert(ThisFromVoid(context)->m_CallbackHandler);
+ return ThisFromVoid(context)->m_CallbackHandler->CallbackSampleRateDidChange(*ThisFromVoid(context), sRate);
+ }
+ static Long CallbackAsioMessage(void * context, MessageSelector selector, Long value, const void * message, const Double * opt) noexcept {
+ assert(context);
+ assert(ThisFromVoid(context)->m_CallbackHandler);
+ return ThisFromVoid(context)->m_CallbackHandler->CallbackMessage(*ThisFromVoid(context), selector, value, message, opt);
+ }
+ static const Time * CallbackBufferSwitchTimeInfo(void * context, const Time * params, Long doubleBufferIndex, Bool directProcess) noexcept {
+ assert(context);
+ assert(ThisFromVoid(context)->m_CallbackHandler);
+ return ThisFromVoid(context)->m_CallbackHandler->CallbackBufferSwitchTimeInfo(*ThisFromVoid(context), params, doubleBufferIndex, directProcess);
+ }
+
+public:
+ std::string getDriverName() const {
+ DriverName name = "";
+ m_Driver->getDriverName(&name);
+ return name;
+ }
+
+ [[nodiscard]] Long getDriverVersion() const {
+ return m_Driver->getDriverVersion();
+ }
+
+ std::string getErrorMessage() const {
+ ErrorMessage string = "";
+ m_Driver->getErrorMessage(&string);
+ return string;
+ }
+
+ void start() {
+ CheckOK(m_Driver->start());
+ }
+
+ void stop() {
+ CheckOK(m_Driver->stop());
+ }
+
+ Channels getChannels() const {
+ Channels result;
+ CheckOK(m_Driver->getChannels(&result.Input, &result.Output));
+ return result;
+ }
+
+ Latencies getLatencies() const {
+ Latencies result;
+ CheckOK(m_Driver->getLatencies(&result.Input, &result.Output));
+ return result;
+ }
+
+ BufferSizes getBufferSizes() const {
+ BufferSizes result;
+ CheckOK(m_Driver->getBufferSize(&result.Min, &result.Max, &result.Preferred, &result.Granularity));
+ return result;
+ }
+
+ bool canSampleRate(SampleRate sampleRate) const {
+ ErrorCode ec = m_Driver->canSampleRate(sampleRate);
+ if ((ec != ErrorCode::OK) && (ec != ErrorCode::NoClock)) {
+ CheckOK(ec);
+ }
+ return (ec == ErrorCode::OK);
+ }
+
+ SampleRate getSampleRate() const {
+ SampleRate sampleRate = 0.0;
+ ErrorCode ec = m_Driver->getSampleRate(&sampleRate);
+ if ((ec != ErrorCode::OK) && (ec != ErrorCode::NoClock)) {
+ CheckOK(ec);
+ }
+ return sampleRate;
+ }
+
+ void setSampleRate(SampleRate sampleRate) {
+ CheckOK(m_Driver->setSampleRate(sampleRate));
+ }
+
+ std::vector<ClockSource> getClockSources() const {
+ std::vector<ClockSource> clocks(1);
+ Long numSources = 1;
+ CheckOK(m_Driver->getClockSources(clocks.data(), &numSources));
+ if (numSources > 1) {
+ clocks.resize(numSources);
+ CheckOK(m_Driver->getClockSources(clocks.data(), &numSources));
+ }
+ return clocks;
+ }
+
+ void setClockSource(Long reference) {
+ CheckOK(m_Driver->setClockSource(reference));
+ }
+
+ SamplePosition getSamplePosition() const {
+ HiLoLongLong samplePosition = 0;
+ HiLoLongLong systemTime = 0;
+ CheckOK(m_Driver->getSamplePosition(&samplePosition, &systemTime));
+ SamplePosition result;
+ result.samplePosition = samplePosition;
+ result.systemTime = systemTime;
+ return result;
+ }
+
+ ChannelInfo getChannelInfo(Long channel, Bool input) const {
+ ChannelInfo info;
+ info.channel = channel;
+ info.isInput = input;
+ CheckOK(m_Driver->getChannelInfo(&info));
+ return info;
+ }
+
+ template <std::uint64_t AppID1, std::uint64_t AppID2, std::size_t MaxInstances = 256>
+ void createBuffers(std::vector<BufferInfo> & bufferInfos, Long bufferSize, ICallbackHandler & handler) {
+ assert(!m_CallbackHandler);
+ assert(!m_Callbacks);
+ m_CallbackHandler = &handler;
+ m_Callbacks = MultiplexedCallbacks<AppID1, AppID2, MaxInstances>::make(MyContext(), MyCallbacks());
+ try {
+ CheckOKNoOutOfMemory(m_Driver->createBuffers(bufferInfos.data(), static_cast<Long>(bufferInfos.size()), bufferSize, *m_Callbacks));
+ } catch (...) {
+ m_Callbacks = nullptr;
+ m_CallbackHandler = nullptr;
+ throw;
+ }
+ }
+
+ void disposeBuffers() {
+ assert(m_CallbackHandler);
+ assert(m_Callbacks);
+ try {
+ CheckOK(m_Driver->disposeBuffers());
+ } catch (...) {
+ m_Callbacks = nullptr;
+ m_CallbackHandler = nullptr;
+ throw;
+ }
+ m_Callbacks = nullptr;
+ m_CallbackHandler = nullptr;
+ }
+
+ bool controlPanel() {
+ ErrorCode ec = m_Driver->controlPanel();
+ if ((ec != ErrorCode::OK) && (ec != ErrorCode::NotPresent)) {
+ CheckOK(ec);
+ }
+ return (ec == ErrorCode::OK);
+ }
+
+ [[deprecated]] [[nodiscard]] ErrorCode future(FutureSelector selector, void * opt) {
+ return CheckResultOutOfMemory(m_Driver->future(selector, opt));
+ }
+
+ void enableTimeCodeRead() {
+ CheckSUCCESS(m_Driver->future(FutureSelector::EnableTimeCodeRead, nullptr));
+ }
+
+ void disableTimeCodeRead() {
+ CheckSUCCESS(m_Driver->future(FutureSelector::DisableTimeCodeRead, nullptr));
+ }
+
+ void setInputMonitor(InputMonitor & inputMonitor) {
+ CheckSUCCESS(m_Driver->future(FutureSelector::SetInputMonitor, &inputMonitor));
+ }
+
+ void transport(TransportParameters & transportParameters) {
+ CheckSUCCESS(m_Driver->future(FutureSelector::Transport, &transportParameters));
+ }
+
+ void setInputGain(Long channel, Bool input, Long gain) {
+ ChannelControls channelControls;
+ channelControls.channel = channel;
+ channelControls.isInput = input;
+ channelControls.gain = gain;
+ CheckSUCCESS(m_Driver->future(FutureSelector::SetInputGain, &channelControls));
+ }
+
+ Long getInputMeter(Long channel, Bool input) const {
+ ChannelControls channelControls;
+ channelControls.channel = channel;
+ channelControls.isInput = input;
+ CheckSUCCESS(m_Driver->future(FutureSelector::GetInputMeter, &channelControls));
+ return channelControls.meter;
+ }
+
+ void setOutputGain(Long channel, Bool input, Long gain) {
+ ChannelControls channelControls;
+ channelControls.channel = channel;
+ channelControls.isInput = input;
+ channelControls.gain = gain;
+ CheckSUCCESS(m_Driver->future(FutureSelector::SetOutputGain, &channelControls));
+ }
+
+ Long getOutputMeter(Long channel, Bool input) const {
+ ChannelControls channelControls;
+ channelControls.channel = channel;
+ channelControls.isInput = input;
+ CheckSUCCESS(m_Driver->future(FutureSelector::GetOutputMeter, &channelControls));
+ return channelControls.meter;
+ }
+
+ bool canInputMonitor() const {
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanInputMonitor, nullptr));
+ return (ec == ErrorCode::SUCCESS);
+ }
+
+ bool canTimeInfo() const {
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanTimeInfo, nullptr));
+ return (ec == ErrorCode::SUCCESS);
+ }
+
+ bool canTimeCode() const {
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanTimeCode, nullptr));
+ return (ec == ErrorCode::SUCCESS);
+ }
+
+ bool canTransport() const {
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanTransport, nullptr));
+ return (ec == ErrorCode::SUCCESS);
+ }
+
+ bool canInputGain() const {
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanInputGain, nullptr));
+ return (ec == ErrorCode::SUCCESS);
+ }
+
+ bool canInputMeter() const {
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanInputMeter, nullptr));
+ return (ec == ErrorCode::SUCCESS);
+ }
+
+ bool canOutputGain() const {
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanOutputGain, nullptr));
+ return (ec == ErrorCode::SUCCESS);
+ }
+
+ bool canOutputMeter() const {
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanOutputMeter, nullptr));
+ return (ec == ErrorCode::SUCCESS);
+ }
+
+ [[nodiscard]] ErrorCode optionalOne(void * param) {
+ return CheckResultOutOfMemory(m_Driver->future(FutureSelector::OptionalOne, param));
+ }
+
+ void setIoFormat(IoFormatType type) {
+ IoFormat ioFormat;
+ ioFormat.FormatType = type;
+ CheckSUCCESS(m_Driver->future(FutureSelector::SetIoFormat, &ioFormat));
+ }
+
+ IoFormatType getIoFormat() const {
+ IoFormat ioFormat;
+ CheckSUCCESS(m_Driver->future(FutureSelector::GetIoFormat, &ioFormat));
+ return ioFormat.FormatType;
+ }
+
+ bool canDoIoFormat(IoFormatType type) {
+ IoFormat ioFormat;
+ ioFormat.FormatType = type;
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanDoIoFormat, &ioFormat));
+ return (ec == ErrorCode::SUCCESS);
+ }
+
+ bool canReportOverload() const {
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanReportOverload, nullptr));
+ return (ec == ErrorCode::SUCCESS);
+ }
+
+ InternalBufferInfo getInternalBufferSamples() const {
+ InternalBufferInfo internalBufferInfo;
+ ErrorCode ec = CheckResultOutOfMemory(m_Driver->future(FutureSelector::CanReportOverload, &internalBufferInfo));
+ if (ec != ErrorCode::SUCCESS) {
+ return InternalBufferInfo();
+ }
+ return internalBufferInfo;
+ }
+
+ bool canOutputReady() const {
+ ErrorCode ec = m_Driver->outputReady();
+ if ((ec != ErrorCode::OK) && (ec != ErrorCode::NotPresent)) {
+ CheckOK(ec);
+ }
+ return (ec == ErrorCode::OK);
+ }
+
+ void outputReady() {
+ CheckOK(m_Driver->outputReady());
+ }
+};
+
+
+
+} // namespace ASIO_VERSION_NAMESPACE
+
+
+
+} // namespace Modern
+
+
+
+} // namespace ASIO
+
+
+
+#endif // ASIO_ASIOMODERN_HPP
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSampleConvert.hpp b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSampleConvert.hpp
new file mode 100644
index 00000000..106a6a20
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSampleConvert.hpp
@@ -0,0 +1,1100 @@
+
+#ifndef ASIO_ASIOSAMPLECONVERT_HPP
+#define ASIO_ASIOSAMPLECONVERT_HPP
+
+
+
+#include "ASIOVersion.hpp"
+#include "ASIOConfig.hpp"
+#include "ASIOCore.hpp"
+
+#include <algorithm>
+#include <array>
+#include <limits>
+#include <type_traits>
+
+#include "ASIOstdcxx20bit.hpp"
+
+#include <cassert>
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
+
+
+
+namespace ASIO {
+
+
+
+namespace Sample {
+
+
+
+inline namespace ASIO_VERSION_NAMESPACE {
+
+
+
+namespace detail {
+
+
+
+template <typename Type>
+struct TraitsExternal { };
+
+template <>
+struct TraitsExternal<std::int8_t> {
+ using type = std::int8_t;
+ using internal_type = std::int64_t;
+ static constexpr internal_type scale = static_cast<internal_type>(1) << 24;
+};
+template <>
+struct TraitsExternal<std::int16_t> {
+ using type = std::int16_t;
+ using internal_type = std::int64_t;
+ static constexpr internal_type scale = static_cast<internal_type>(1) << 16;
+};
+template <>
+struct TraitsExternal<std::int32_t> {
+ using type = std::int32_t;
+ using internal_type = std::int64_t;
+ static constexpr internal_type scale = static_cast<internal_type>(1) << 0;
+};
+template <>
+struct TraitsExternal<float> {
+ using type = float;
+ using internal_type = float;
+};
+template <>
+struct TraitsExternal<double> {
+ using type = double;
+ using internal_type = double;
+};
+template <>
+struct TraitsExternal<long double> {
+ using type = long double;
+ using internal_type = double;
+};
+
+
+
+struct Int16MSB {
+ std::array<std::byte, 2> data;
+};
+struct Int24MSB {
+ std::array<std::byte, 3> data;
+};
+struct Int32MSB {
+ std::array<std::byte, 4> data;
+};
+struct Int32MSB16 {
+ std::array<std::byte, 4> data;
+};
+struct Int32MSB18 {
+ std::array<std::byte, 4> data;
+};
+struct Int32MSB20 {
+ std::array<std::byte, 4> data;
+};
+struct Int32MSB24 {
+ std::array<std::byte, 4> data;
+};
+struct Float32MSB {
+ std::array<std::byte, 4> data;
+};
+struct Float64MSB {
+ std::array<std::byte, 8> data;
+};
+
+struct Int16LSB {
+ std::array<std::byte, 2> data;
+};
+struct Int24LSB {
+ std::array<std::byte, 3> data;
+};
+struct Int32LSB {
+ std::array<std::byte, 4> data;
+};
+struct Int32LSB16 {
+ std::array<std::byte, 4> data;
+};
+struct Int32LSB18 {
+ std::array<std::byte, 4> data;
+};
+struct Int32LSB20 {
+ std::array<std::byte, 4> data;
+};
+struct Int32LSB24 {
+ std::array<std::byte, 4> data;
+};
+struct Float32LSB {
+ std::array<std::byte, 4> data;
+};
+struct Float64LSB {
+ std::array<std::byte, 8> data;
+};
+
+
+
+template <typename Type>
+struct Types { };
+
+template <>
+struct Types<detail::Int16MSB> {
+ using type = detail::Int16MSB;
+ static constexpr SampleType sample_type = SampleType::Int16MSB;
+ using internal_type = std::int64_t;
+ using value_type = std::int16_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 16;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = true;
+};
+template <>
+struct Types<detail::Int24MSB> {
+ using type = detail::Int24MSB;
+ static constexpr SampleType sample_type = SampleType::Int24MSB;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 24;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = true;
+};
+template <>
+struct Types<detail::Int32MSB> {
+ using type = detail::Int32MSB;
+ static constexpr SampleType sample_type = SampleType::Int32MSB;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 32;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = true;
+};
+template <>
+struct Types<detail::Int32MSB16> {
+ using type = detail::Int32MSB16;
+ static constexpr SampleType sample_type = SampleType::Int32MSB16;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 16;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = true;
+};
+template <>
+struct Types<detail::Int32MSB18> {
+ using type = detail::Int32MSB18;
+ static constexpr SampleType sample_type = SampleType::Int32MSB18;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 18;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = true;
+};
+template <>
+struct Types<detail::Int32MSB20> {
+ using type = detail::Int32MSB20;
+ static constexpr SampleType sample_type = SampleType::Int32MSB20;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 20;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = true;
+};
+template <>
+struct Types<detail::Int32MSB24> {
+ using type = detail::Int32MSB24;
+ static constexpr SampleType sample_type = SampleType::Int32MSB24;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 24;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = true;
+};
+template <>
+struct Types<detail::Float32MSB> {
+ using type = detail::Float32MSB;
+ static constexpr SampleType sample_type = SampleType::Float32MSB;
+ using internal_type = float;
+ using value_type = float;
+ using unsigned_type = float;
+ static constexpr std::size_t valid_bits = 32;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = true;
+};
+template <>
+struct Types<detail::Float64MSB> {
+ using type = detail::Float64MSB;
+ static constexpr SampleType sample_type = SampleType::Float64MSB;
+ using internal_type = double;
+ using value_type = double;
+ using unsigned_type = double;
+ static constexpr std::size_t valid_bits = 64;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = true;
+};
+
+template <>
+struct Types<detail::Int16LSB> {
+ using type = detail::Int16LSB;
+ static constexpr SampleType sample_type = SampleType::Int16MSB;
+ using internal_type = std::int64_t;
+ using value_type = std::int16_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 16;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = false;
+};
+template <>
+struct Types<detail::Int24LSB> {
+ using type = detail::Int24LSB;
+ static constexpr SampleType sample_type = SampleType::Int24LSB;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 24;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = false;
+};
+template <>
+struct Types<detail::Int32LSB> {
+ using type = detail::Int32LSB;
+ static constexpr SampleType sample_type = SampleType::Int32LSB;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 32;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = false;
+};
+template <>
+struct Types<detail::Int32LSB16> {
+ using type = detail::Int32LSB16;
+ static constexpr SampleType sample_type = SampleType::Int32LSB16;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 16;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = false;
+};
+template <>
+struct Types<detail::Int32LSB18> {
+ using type = detail::Int32LSB18;
+ static constexpr SampleType sample_type = SampleType::Int32LSB18;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 18;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = false;
+};
+template <>
+struct Types<detail::Int32LSB20> {
+ using type = detail::Int32LSB20;
+ static constexpr SampleType sample_type = SampleType::Int32LSB20;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 20;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = false;
+};
+template <>
+struct Types<detail::Int32LSB24> {
+ using type = detail::Int32LSB24;
+ static constexpr SampleType sample_type = SampleType::Int32LSB24;
+ using internal_type = std::int64_t;
+ using value_type = std::int32_t;
+ using unsigned_type = std::make_unsigned<value_type>::type;
+ static constexpr std::size_t valid_bits = 24;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = false;
+};
+template <>
+struct Types<detail::Float32LSB> {
+ using type = detail::Float32LSB;
+ static constexpr SampleType sample_type = SampleType::Float32LSB;
+ using internal_type = float;
+ using value_type = float;
+ using unsigned_type = float;
+ static constexpr std::size_t valid_bits = 32;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = false;
+};
+template <>
+struct Types<detail::Float64LSB> {
+ using type = detail::Float64LSB;
+ static constexpr SampleType sample_type = SampleType::Float64LSB;
+ using internal_type = double;
+ using value_type = double;
+ using unsigned_type = double;
+ static constexpr std::size_t valid_bits = 64;
+ static constexpr bool is_float = std::is_floating_point<value_type>::value;
+ static constexpr bool is_be = false;
+};
+
+
+
+template <typename T>
+constexpr T clip(T x) noexcept = delete;
+template <>
+constexpr std::int64_t clip<std::int64_t>(std::int64_t q32) noexcept {
+ return std::clamp(q32, static_cast<std::int64_t>(std::numeric_limits<std::int32_t>::min()), static_cast<std::int64_t>(std::numeric_limits<std::int32_t>::max()));
+}
+template <>
+constexpr double clip<double>(double dbl) noexcept {
+ return std::clamp(dbl, -1.0, 1.0);
+}
+template <>
+constexpr float clip<float>(float flt) noexcept {
+ return std::clamp(flt, -1.0f, 1.0f);
+}
+
+
+
+template <typename Tdst, typename Tsrc>
+inline Tdst convert_internal(Tsrc x) noexcept = delete;
+template <>
+inline std::int64_t convert_internal<std::int64_t, std::int64_t>(std::int64_t q32) noexcept {
+ return q32;
+}
+template <>
+inline std::int64_t convert_internal<std::int64_t, double>(double dbl) noexcept {
+ return std::llround(dbl * static_cast<double>(1ll << 32));
+}
+template <>
+inline std::int64_t convert_internal<std::int64_t, float>(float flt) noexcept {
+ return std::llround(flt * static_cast<float>(1ll << 32));
+}
+template <>
+inline double convert_internal<double, std::int64_t>(std::int64_t q32) noexcept {
+ return static_cast<double>(q32) * (1.0 / static_cast<double>(1ll << 32));
+}
+template <>
+inline double convert_internal<double, double>(double dbl) noexcept {
+ return dbl;
+}
+template <>
+inline double convert_internal<double, float>(float flt) noexcept {
+ return static_cast<double>(flt);
+}
+template <>
+inline float convert_internal<float, std::int64_t>(std::int64_t q32) noexcept {
+ return static_cast<float>(q32) * (1.0f / static_cast<float>(1ll << 32));
+}
+template <>
+inline float convert_internal<float, double>(double dbl) noexcept {
+ return static_cast<float>(dbl);
+}
+template <>
+inline float convert_internal<float, float>(float flt) noexcept {
+ return flt;
+}
+
+
+
+template <typename SampleType>
+inline SampleType sample_from_value(typename Types<SampleType>::value_type val) noexcept {
+ if constexpr (Types<SampleType>::is_float) {
+ static_assert(sizeof(SampleType) == sizeof(typename Types<SampleType>::value_type));
+ static_assert((stdcxx20::endian::native == stdcxx20::endian::little) || (stdcxx20::endian::native == stdcxx20::endian::big));
+ SampleType result = stdcxx20::bit_cast<SampleType>(val);
+ if constexpr (Types<SampleType>::is_be) {
+ if constexpr (stdcxx20::endian::native == stdcxx20::endian::little) {
+ std::reverse(std::begin(result.data), std::end(result.data));
+ }
+ } else {
+ if constexpr (stdcxx20::endian::native == stdcxx20::endian::big) {
+ std::reverse(std::begin(result.data), std::end(result.data));
+ }
+ }
+ return result;
+ } else {
+ SampleType result{};
+ typename Types<SampleType>::unsigned_type uval = static_cast<typename Types<SampleType>::unsigned_type>(val);
+ for (std::size_t byte = 0; byte < sizeof(SampleType); ++byte) {
+ if constexpr (Types<SampleType>::is_be) {
+ result.data[sizeof(SampleType) - 1 - byte] = std::byte{static_cast<std::uint8_t>(uval)};
+ } else {
+ result.data[byte] = std::byte{static_cast<std::uint8_t>(uval)};
+ }
+ uval /= (1u << 8);
+ }
+ return result;
+ }
+}
+
+template <typename SampleType>
+inline typename Types<SampleType>::value_type value_from_sample(SampleType smp) noexcept {
+ if constexpr (Types<SampleType>::is_float) {
+ static_assert(sizeof(SampleType) == sizeof(typename Types<SampleType>::value_type));
+ static_assert((stdcxx20::endian::native == stdcxx20::endian::little) || (stdcxx20::endian::native == stdcxx20::endian::big));
+ if constexpr (Types<SampleType>::is_be) {
+ if constexpr (stdcxx20::endian::native == stdcxx20::endian::little) {
+ std::reverse(std::begin(smp.data), std::end(smp.data));
+ }
+ } else {
+ if constexpr (stdcxx20::endian::native == stdcxx20::endian::big) {
+ std::reverse(std::begin(smp.data), std::end(smp.data));
+ }
+ }
+ return stdcxx20::bit_cast<typename Types<SampleType>::value_type>(smp.data);
+ } else {
+ typename Types<SampleType>::unsigned_type uval = 0;
+ for (std::size_t byte = 0; byte < sizeof(SampleType); ++byte) {
+ uval *= (1u << 8);
+ if constexpr (Types<SampleType>::is_be) {
+ uval |= std::to_integer<std::uint8_t>(smp.data[byte]);
+ } else {
+ uval |= std::to_integer<std::uint8_t>(smp.data[sizeof(SampleType) - 1 - byte]);
+ }
+ }
+ return static_cast<typename Types<SampleType>::value_type>(uval);
+ }
+}
+
+
+
+template <typename SampleType>
+inline typename Types<SampleType>::value_type value_from_internal(typename Types<SampleType>::internal_type smp_int) noexcept {
+ if constexpr (Types<SampleType>::is_float) {
+ return static_cast<typename Types<SampleType>::value_type>(smp_int);
+ } else {
+ return static_cast<typename Types<SampleType>::value_type>(clip(smp_int) / (static_cast<typename Types<SampleType>::internal_type>(1) << (32 - Types<SampleType>::valid_bits)));
+ }
+}
+
+template <typename SampleType>
+inline typename Types<SampleType>::internal_type internal_from_value(typename Types<SampleType>::value_type val) noexcept {
+ if constexpr (Types<SampleType>::is_float) {
+ return static_cast<typename Types<SampleType>::internal_type>(val);
+ } else {
+ return clip(static_cast<typename Types<SampleType>::internal_type>(val) * (static_cast<typename Types<SampleType>::internal_type>(1) << (32 - Types<SampleType>::valid_bits)));
+ }
+}
+
+
+
+template <typename ExternalType>
+inline typename TraitsExternal<ExternalType>::internal_type internal_from_external(ExternalType x) noexcept {
+ static_assert(std::is_floating_point<typename TraitsExternal<ExternalType>::internal_type>::value == std::is_floating_point<ExternalType>::value);
+ if constexpr (std::is_floating_point<ExternalType>::value) {
+ return static_cast<typename TraitsExternal<ExternalType>::internal_type>(x);
+ } else {
+ return static_cast<typename TraitsExternal<ExternalType>::internal_type>(x) * TraitsExternal<ExternalType>::scale;
+ }
+}
+
+template <typename ExternalType>
+inline ExternalType external_from_internal(typename TraitsExternal<ExternalType>::internal_type x) noexcept {
+ static_assert(std::is_floating_point<typename TraitsExternal<ExternalType>::internal_type>::value == std::is_floating_point<ExternalType>::value);
+ if constexpr (std::is_floating_point<ExternalType>::value) {
+ return static_cast<ExternalType>(x);
+ } else {
+ return static_cast<ExternalType>(clip(x) / TraitsExternal<ExternalType>::scale);
+ }
+}
+
+
+
+template <typename SampleType, typename ExternalType>
+inline SampleType sample_from_external(ExternalType x) noexcept {
+ return sample_from_value<SampleType>(value_from_internal<SampleType>(convert_internal<typename Types<SampleType>::internal_type, typename TraitsExternal<ExternalType>::internal_type>(internal_from_external<ExternalType>(x))));
+}
+
+template <typename ExternalType, typename SampleType>
+inline ExternalType external_from_sample(SampleType x) noexcept {
+ return external_from_internal<ExternalType>(convert_internal<typename TraitsExternal<ExternalType>::internal_type, typename Types<SampleType>::internal_type>(internal_from_value<SampleType>(value_from_sample<SampleType>(x))));
+}
+
+
+
+template <typename Tdst>
+inline void ClearBuffer(Tdst * dst, std::size_t dst_stride, std::size_t count) noexcept {
+ for (std::size_t i = 0; i < count; ++i)
+ {
+ Tdst val{};
+ std::fill(val.data.begin(), val.data.end(), std::byte{0});
+ *dst = val;
+ dst += dst_stride;
+ }
+}
+
+
+
+template <typename Tdst, typename Tsrc, typename Tfunc>
+inline void ConvertBuffer(Tdst * dst, std::size_t dst_stride, const Tsrc * src, std::size_t src_stride, std::size_t count, Tfunc func) noexcept(noexcept(func(Tsrc()))) {
+ for (std::size_t i = 0; i < count; ++i)
+ {
+ *dst = func(*src);
+ src += src_stride;
+ dst += dst_stride;
+ }
+}
+
+
+
+} // namespace detail
+
+
+
+inline void ClearBufferASIO(void * dst, SampleType type, std::size_t count) noexcept {
+ switch (type) {
+ case SampleType::Int16MSB:
+ {
+ using SampleType = detail::Int16MSB;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int16LSB:
+ {
+ using SampleType = detail::Int16LSB;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int24MSB:
+ {
+ using SampleType = detail::Int24MSB;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int24LSB:
+ {
+ using SampleType = detail::Int24LSB;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int32MSB:
+ {
+ using SampleType = detail::Int32MSB;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int32LSB:
+ {
+ using SampleType = detail::Int32LSB;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Float32MSB:
+ {
+ using SampleType = detail::Float32MSB;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Float32LSB:
+ {
+ using SampleType = detail::Float32LSB;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Float64MSB:
+ {
+ using SampleType = detail::Float64MSB;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Float64LSB:
+ {
+ using SampleType = detail::Float64LSB;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int32MSB16:
+ {
+ using SampleType = detail::Int32MSB16;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int32LSB16:
+ {
+ using SampleType = detail::Int32LSB16;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int32MSB18:
+ {
+ using SampleType = detail::Int32MSB18;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int32LSB18:
+ {
+ using SampleType = detail::Int32LSB18;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int32MSB20:
+ {
+ using SampleType = detail::Int32MSB20;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int32LSB20:
+ {
+ using SampleType = detail::Int32LSB20;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int32MSB24:
+ {
+ using SampleType = detail::Int32MSB24;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ case SampleType::Int32LSB24:
+ {
+ using SampleType = detail::Int32LSB24;
+ detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
+ }
+ break;
+ default:
+ assert(false);
+ break;
+ }
+}
+
+
+template <typename Tdst>
+inline void CopyRawFromASIO(Tdst * dst, std::size_t dst_stride, const void * src, std::size_t count) noexcept {
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const Tdst *>(src), 1, count, [](Tdst smp) { return smp; });
+}
+
+template <typename Tsrc>
+inline void CopyRawToASIO(void * dst, const Tsrc * src, std::size_t src_stride, std::size_t count) noexcept {
+ detail::ConvertBuffer(static_cast<Tsrc *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return smp; });
+}
+
+
+
+template <typename Tdst>
+inline void ConvertFromASIO(Tdst * dst, std::size_t dst_stride, SampleType type, const void * src, std::size_t count) noexcept {
+ switch (type) {
+ case SampleType::Int16MSB:
+ {
+ using SampleType = detail::Int16MSB;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int16LSB:
+ {
+ using SampleType = detail::Int16LSB;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int24MSB:
+ {
+ using SampleType = detail::Int24MSB;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int24LSB:
+ {
+ using SampleType = detail::Int24LSB;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int32MSB:
+ {
+ using SampleType = detail::Int32MSB;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int32LSB:
+ {
+ using SampleType = detail::Int32LSB;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Float32MSB:
+ {
+ using SampleType = detail::Float32MSB;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Float32LSB:
+ {
+ using SampleType = detail::Float32LSB;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Float64MSB:
+ {
+ using SampleType = detail::Float64MSB;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Float64LSB:
+ {
+ using SampleType = detail::Float64LSB;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int32MSB16:
+ {
+ using SampleType = detail::Int32MSB16;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int32LSB16:
+ {
+ using SampleType = detail::Int32LSB16;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int32MSB18:
+ {
+ using SampleType = detail::Int32MSB18;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int32LSB18:
+ {
+ using SampleType = detail::Int32LSB18;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int32MSB20:
+ {
+ using SampleType = detail::Int32MSB20;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int32LSB20:
+ {
+ using SampleType = detail::Int32LSB20;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int32MSB24:
+ {
+ using SampleType = detail::Int32MSB24;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ case SampleType::Int32LSB24:
+ {
+ using SampleType = detail::Int32LSB24;
+ detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
+ }
+ break;
+ default:
+ assert(false);
+ break;
+ }
+}
+
+template <typename Tsrc>
+inline void ConvertToASIO(void * dst, SampleType type, const Tsrc * src, std::size_t src_stride, std::size_t count) noexcept {
+ switch (type) {
+ case SampleType::Int16MSB:
+ {
+ using SampleType = detail::Int16MSB;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int16LSB:
+ {
+ using SampleType = detail::Int16LSB;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int24MSB:
+ {
+ using SampleType = detail::Int24MSB;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int24LSB:
+ {
+ using SampleType = detail::Int24LSB;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int32MSB:
+ {
+ using SampleType = detail::Int32MSB;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int32LSB:
+ {
+ using SampleType = detail::Int32LSB;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Float32MSB:
+ {
+ using SampleType = detail::Float32MSB;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Float32LSB:
+ {
+ using SampleType = detail::Float32LSB;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Float64MSB:
+ {
+ using SampleType = detail::Float64MSB;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Float64LSB:
+ {
+ using SampleType = detail::Float64LSB;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int32MSB16:
+ {
+ using SampleType = detail::Int32MSB16;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int32LSB16:
+ {
+ using SampleType = detail::Int32LSB16;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int32MSB18:
+ {
+ using SampleType = detail::Int32MSB18;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int32LSB18:
+ {
+ using SampleType = detail::Int32LSB18;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int32MSB20:
+ {
+ using SampleType = detail::Int32MSB20;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int32LSB20:
+ {
+ using SampleType = detail::Int32LSB20;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int32MSB24:
+ {
+ using SampleType = detail::Int32MSB24;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ case SampleType::Int32LSB24:
+ {
+ using SampleType = detail::Int32LSB24;
+ detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
+ }
+ break;
+ default:
+ assert(false);
+ break;
+ }
+}
+
+
+
+struct Traits {
+ std::size_t size_bytes = 0;
+ std::size_t valid_bits = 0;
+ bool is_float = false;
+ bool is_be = false;
+ constexpr explicit Traits(SampleType type) noexcept {
+ switch (type) {
+ case SampleType::Int16MSB:
+ {
+ using Type = detail::Types<detail::Int16MSB>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int24MSB:
+ {
+ using Type = detail::Types<detail::Int24MSB>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int32MSB:
+ {
+ using Type = detail::Types<detail::Int32MSB>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Float32MSB:
+ {
+ using Type = detail::Types<detail::Float32MSB>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Float64MSB:
+ {
+ using Type = detail::Types<detail::Float64MSB>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int32MSB16:
+ {
+ using Type = detail::Types<detail::Int32MSB16>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int32MSB18:
+ {
+ using Type = detail::Types<detail::Int32MSB18>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int32MSB20:
+ {
+ using Type = detail::Types<detail::Int32MSB20>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int32MSB24:
+ {
+ using Type = detail::Types<detail::Int32MSB24>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int16LSB:
+ {
+ using Type = detail::Types<detail::Int16LSB>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int24LSB:
+ {
+ using Type = detail::Types<detail::Int24LSB>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int32LSB:
+ {
+ using Type = detail::Types<detail::Int32LSB>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Float32LSB:
+ {
+ using Type = detail::Types<detail::Float32LSB>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Float64LSB:
+ {
+ using Type = detail::Types<detail::Float64LSB>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int32LSB16:
+ {
+ using Type = detail::Types<detail::Int32LSB16>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int32LSB18:
+ {
+ using Type = detail::Types<detail::Int32LSB18>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int32LSB20:
+ {
+ using Type = detail::Types<detail::Int32LSB20>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ case SampleType::Int32LSB24:
+ {
+ using Type = detail::Types<detail::Int32LSB24>;
+ size_bytes = sizeof(Type::type);
+ valid_bits = Type::valid_bits;
+ is_float = Type::is_float;
+ is_be = Type::is_be;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+};
+
+
+
+} // namespace ASIO_VERSION_NAMESPACE
+
+
+
+} // namespace Sample
+
+
+
+} // namespace ASIO
+
+
+
+#endif // ASIO_ASIOSAMPLECONVERT_HPP \ No newline at end of file
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSystemWindows.hpp b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSystemWindows.hpp
new file mode 100644
index 00000000..2473dd70
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSystemWindows.hpp
@@ -0,0 +1,511 @@
+
+#ifndef ASIO_ASIOSYSTEMWINDOWS_HPP
+#define ASIO_ASIOSYSTEMWINDOWS_HPP
+
+
+
+#include "ASIOVersion.hpp"
+#include "ASIOConfig.hpp"
+#include "ASIOCore.hpp"
+
+#include <exception>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include <cassert>
+
+#if ASIO_SYSTEM_WINDOWS
+#include <windows.h>
+#if !defined(NTDDI_VERSION)
+#error "NTDDI_VERSION undefined"
+#endif
+#if !defined(_WIN32_WINNT)
+#error "_WIN32_WINNT undefined"
+#endif
+#include <avrt.h>
+#endif // ASIO_SYSTEM_WINDOWS
+
+
+
+#if ASIO_SYSTEM_WINDOWS
+#if ASIO_HAVE_PRAGMA_COMMENT_LIB
+#pragma comment(lib, "kernel32.lib")
+#pragma comment(lib, "advapi32.lib")
+#pragma comment(lib, "avrt.lib")
+#endif // ASIO_HAVE_PRAGMA_COMMENT_LIB
+#endif // ASIO_SYSTEM_WINDOWS
+
+
+
+namespace ASIO {
+
+
+
+#if ASIO_SYSTEM_WINDOWS
+
+
+
+namespace Windows {
+
+
+
+inline namespace ASIO_VERSION_NAMESPACE {
+
+
+
+static_assert(NTDDI_VERSION >= NTDDI_WIN7);
+static_assert(_WIN32_WINNT >= _WIN32_WINNT_WIN7);
+
+
+
+#if defined(UNICODE)
+inline namespace Unicode {
+#else
+inline namespace Ansi {
+#endif
+
+
+
+struct DriverInfo {
+ std::basic_string<TCHAR> Key;
+ std::basic_string<TCHAR> Id;
+ CLSID Clsid{};
+ std::basic_string<TCHAR> Name;
+ std::basic_string<TCHAR> Description;
+ std::basic_string<TCHAR> DisplayName() const {
+ if (Description.empty()) {
+ return Key;
+ }
+ return Description;
+ }
+};
+
+
+class HKey {
+private:
+ HKEY m_Key = NULL;
+
+public:
+ HKey() = default;
+ HKey(const HKey &) = delete;
+ HKey & operator=(const HKey &) = delete;
+ ~HKey() {
+ if (m_Key) {
+ RegCloseKey(m_Key);
+ }
+ }
+ operator HKEY &() {
+ return m_Key;
+ }
+ operator HKEY *() {
+ return &m_Key;
+ }
+};
+
+
+inline LRESULT CheckLRESULTOutOfMemory(LRESULT lr) {
+ if ((lr == ERROR_NOT_ENOUGH_MEMORY) || (lr == ERROR_OUTOFMEMORY)) {
+ throw std::bad_alloc();
+ }
+ return lr;
+}
+
+inline HRESULT CheckHRESULTOutOfMemory(HRESULT hr) {
+ if (hr == E_OUTOFMEMORY) {
+ throw std::bad_alloc();
+ }
+ return hr;
+}
+
+
+inline std::vector<DriverInfo> EnumerateDrivers() {
+ std::vector<DriverInfo> drivers;
+ HKey hkAsioEnum;
+ if (CheckLRESULTOutOfMemory(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\ASIO"), 0, KEY_READ, hkAsioEnum)) != ERROR_SUCCESS) {
+ return drivers;
+ }
+ DWORD numSubKeys = 0;
+ DWORD maxSubKeyLen = 0;
+ if (CheckLRESULTOutOfMemory(RegQueryInfoKey(hkAsioEnum, NULL, NULL, NULL, &numSubKeys, &maxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL)) != ERROR_SUCCESS) {
+ return drivers;
+ }
+ for (DWORD i = 0; i < numSubKeys; ++i) {
+ std::vector<TCHAR> bufKey(static_cast<std::size_t>(maxSubKeyLen) + 1);
+ DWORD lenKey = static_cast<DWORD>(bufKey.size());
+ if (CheckLRESULTOutOfMemory(RegEnumKeyEx(hkAsioEnum, i, bufKey.data(), &lenKey, NULL, NULL, NULL, NULL)) != ERROR_SUCCESS) {
+ continue;
+ }
+ std::basic_string<TCHAR> key(bufKey.data(), bufKey.data() + lenKey);
+ HKey hkDriver;
+ if (CheckLRESULTOutOfMemory(RegOpenKeyEx(hkAsioEnum, key.c_str(), 0, KEY_READ, hkDriver)) != ERROR_SUCCESS) {
+ continue;
+ }
+ DWORD maxValueLen = 0;
+ if (CheckLRESULTOutOfMemory(RegQueryInfoKey(hkDriver, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &maxValueLen, NULL, NULL)) != ERROR_SUCCESS) {
+ continue;
+ }
+ std::vector<TCHAR> bufClsid(static_cast<std::size_t>(maxValueLen) + 1);
+ DWORD lenClsid = static_cast<DWORD>(bufClsid.size()) * sizeof(TCHAR);
+ DWORD typeClsid = REG_SZ;
+ if (CheckLRESULTOutOfMemory(RegQueryValueEx(hkDriver, TEXT("CLSID"), NULL, &typeClsid, reinterpret_cast<LPBYTE>(bufClsid.data()), &lenClsid)) != ERROR_SUCCESS) {
+ continue;
+ }
+ std::basic_string<TCHAR> strClsid = std::basic_string<TCHAR>(bufClsid.data(), bufClsid.data() + (lenClsid / sizeof(TCHAR))).c_str();
+ std::vector<OLECHAR> oleClsid(strClsid.c_str(), strClsid.c_str() + strClsid.length() + 1);
+ CLSID clsid = CLSID();
+ if (CheckHRESULTOutOfMemory(CLSIDFromString(oleClsid.data(), &clsid)) != NOERROR) {
+ continue;
+ }
+ std::vector<TCHAR> bufName(static_cast<std::size_t>(maxValueLen) + 1);
+ DWORD lenName = static_cast<DWORD>(bufName.size()) * sizeof(TCHAR);
+ DWORD typeName = REG_SZ;
+ std::basic_string<TCHAR> name;
+ if (CheckLRESULTOutOfMemory(RegQueryValueEx(hkDriver, TEXT(""), NULL, &typeName, reinterpret_cast<LPBYTE>(bufName.data()), &lenName)) == ERROR_SUCCESS) {
+ name = std::basic_string<TCHAR>(bufName.data(), bufName.data() + (lenName / sizeof(TCHAR))).c_str();
+ }
+ std::vector<TCHAR> bufDesc(static_cast<std::size_t>(maxValueLen) + 1);
+ DWORD lenDesc = static_cast<DWORD>(bufDesc.size()) * sizeof(TCHAR);
+ DWORD typeDesc = REG_SZ;
+ std::basic_string<TCHAR> desc;
+ if (CheckLRESULTOutOfMemory(RegQueryValueEx(hkDriver, TEXT("Description"), NULL, &typeDesc, reinterpret_cast<LPBYTE>(bufDesc.data()), &lenDesc)) == ERROR_SUCCESS) {
+ desc = std::basic_string<TCHAR>(bufDesc.data(), bufDesc.data() + (lenDesc / sizeof(TCHAR))).c_str();
+ }
+ DriverInfo info;
+ info.Key = key;
+ info.Id = strClsid;
+ info.Clsid = clsid;
+ info.Name = name;
+ info.Description = desc;
+ drivers.push_back(std::move(info));
+ }
+ return drivers;
+}
+
+
+[[nodiscard]] inline ISystemDriver * OpenDriver(CLSID clsid) {
+ ISystemDriver * driver = nullptr;
+ if (CheckHRESULTOutOfMemory(CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, clsid, reinterpret_cast<void **>(&driver))) != S_OK) {
+ return nullptr;
+ }
+ return driver;
+}
+
+inline ULONG CloseDriver(ISystemDriver * driver) {
+ return driver->Release();
+}
+
+
+struct DriverLoadFailed
+ : public std::runtime_error {
+ DriverLoadFailed()
+ : std::runtime_error("ASIO Driver load failed.") {
+ return;
+ }
+};
+
+
+struct DriverInitFailed
+ : public std::runtime_error {
+ DriverInitFailed()
+ : std::runtime_error("ASIO Driver init failed.") {
+ return;
+ }
+};
+
+
+class Driver
+ : public IDriver {
+
+private:
+ ISystemDriver * m_Driver = nullptr;
+
+public:
+ explicit Driver(CLSID clsid, HWND wnd) {
+ m_Driver = openDriver(clsid);
+ if (!m_Driver) {
+ throw DriverLoadFailed();
+ }
+ if (!initDriver(wnd)) {
+ closeDriver(m_Driver);
+ throw DriverInitFailed();
+ }
+ }
+
+ Driver(const Driver &) = delete;
+
+ Driver & operator=(const Driver &) = delete;
+
+ ~Driver() override {
+ closeDriver(m_Driver);
+ }
+
+private:
+ ISystemDriver * openDriver(CLSID clsid) {
+ return OpenDriver(clsid);
+ }
+
+ ULONG closeDriver(ISystemDriver * driver) {
+ return driver->Release();
+ }
+
+private:
+ Bool initDriver(HWND sysHandle) {
+ return static_cast<Bool>(m_Driver->init(reinterpret_cast<SysHandle>(sysHandle)));
+ }
+
+public:
+ void getDriverName(DriverName * name) final {
+ return m_Driver->getDriverName(name);
+ }
+ [[nodiscard]] Long getDriverVersion() final {
+ return m_Driver->getDriverVersion();
+ }
+ void getErrorMessage(ErrorMessage * string) final {
+ return m_Driver->getErrorMessage(string);
+ }
+ [[nodiscard]] ErrorCode start() final {
+ return m_Driver->start();
+ }
+ [[nodiscard]] ErrorCode stop() final {
+ return m_Driver->stop();
+ }
+ [[nodiscard]] ErrorCode getChannels(Long * numInputChannels, Long * numOutputChannels) final {
+ return m_Driver->getChannels(numInputChannels, numOutputChannels);
+ }
+ [[nodiscard]] ErrorCode getLatencies(Long * inputLatency, Long * outputLatency) final {
+ return m_Driver->getLatencies(inputLatency, outputLatency);
+ }
+ [[nodiscard]] ErrorCode getBufferSize(Long * minSize, Long * maxSize, Long * preferredSize, Long * granularity) final {
+ return m_Driver->getBufferSize(minSize, maxSize, preferredSize, granularity);
+ }
+ [[nodiscard]] ErrorCode canSampleRate(SampleRate sampleRate) final {
+ return m_Driver->canSampleRate(sampleRate);
+ }
+ [[nodiscard]] ErrorCode getSampleRate(SampleRate * sampleRate) final {
+ return m_Driver->getSampleRate(sampleRate);
+ }
+ [[nodiscard]] ErrorCode setSampleRate(SampleRate sampleRate) final {
+ return m_Driver->setSampleRate(sampleRate);
+ }
+ [[nodiscard]] ErrorCode getClockSources(ClockSource * clocks, Long * numSources) final {
+ return m_Driver->getClockSources(clocks, numSources);
+ }
+ [[nodiscard]] ErrorCode setClockSource(Long reference) final {
+ return m_Driver->setClockSource(reference);
+ }
+ [[nodiscard]] ErrorCode getSamplePosition(HiLoLongLong * samplePosition, HiLoLongLong * timeStamp) final {
+ return m_Driver->getSamplePosition(samplePosition, timeStamp);
+ }
+ [[nodiscard]] ErrorCode getChannelInfo(ChannelInfo * info) final {
+ return m_Driver->getChannelInfo(info);
+ }
+ [[nodiscard]] ErrorCode createBuffers(BufferInfo * bufferInfos, Long numChannels, Long bufferSize, Callbacks const * callbacks) final {
+ return m_Driver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks);
+ }
+ [[nodiscard]] ErrorCode disposeBuffers() final {
+ return m_Driver->disposeBuffers();
+ }
+ [[nodiscard]] ErrorCode controlPanel() final {
+ return m_Driver->controlPanel();
+ }
+ [[nodiscard]] ErrorCode future(FutureSelector selector, void * opt) final {
+ return m_Driver->future(selector, opt);
+ }
+ [[nodiscard]] ErrorCode outputReady() final {
+ return m_Driver->outputReady();
+ }
+};
+
+
+
+class IBufferSwitchDispatcher {
+public:
+ virtual ~IBufferSwitchDispatcher() = default;
+
+public:
+ virtual void Dispatch(std::size_t bufferIndex) = 0;
+};
+
+class BufferSwitchDispatcherBase
+ : public IBufferSwitchDispatcher {
+
+private:
+ HANDLE m_hBufferSwitch[2] = {NULL, NULL};
+
+ HANDLE m_hStarted = NULL;
+ HANDLE m_hStopRequest = NULL;
+
+ HANDLE m_hThread = NULL;
+
+public:
+ BufferSwitchDispatcherBase() {
+ m_hBufferSwitch[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (m_hBufferSwitch[0] == NULL) {
+ goto error;
+ }
+ m_hBufferSwitch[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (m_hBufferSwitch[1] == NULL) {
+ goto error;
+ }
+ m_hStarted = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (m_hStarted == NULL) {
+ goto error;
+ }
+ m_hStopRequest = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (m_hStopRequest == NULL) {
+ goto error;
+ }
+ m_hThread = CreateThread(NULL, 0, &ThreadProc, this, 0, NULL);
+ if (m_hThread == NULL) {
+ goto error;
+ }
+ if (WaitForSingleObject(m_hStarted, INFINITE) != WAIT_OBJECT_0) {
+ if (SetEvent(m_hStopRequest) != TRUE) {
+ goto error;
+ }
+ if (WaitForSingleObject(m_hThread, INFINITE) != WAIT_OBJECT_0) {
+ goto error;
+ }
+ goto error;
+ }
+ return;
+error:
+ if (m_hThread != NULL) {
+ CloseHandle(m_hThread);
+ }
+ if (m_hStopRequest != NULL) {
+ CloseHandle(m_hStopRequest);
+ }
+ if (m_hStarted != NULL) {
+ CloseHandle(m_hStarted);
+ }
+ if (m_hBufferSwitch[1] != NULL) {
+ CloseHandle(m_hBufferSwitch[1]);
+ }
+ if (m_hBufferSwitch[0] != NULL) {
+ CloseHandle(m_hBufferSwitch[0]);
+ }
+ throw std::bad_alloc();
+ }
+
+ ~BufferSwitchDispatcherBase() override {
+ SetEvent(m_hStopRequest);
+ WaitForSingleObject(m_hThread, INFINITE);
+ CloseHandle(m_hThread);
+ CloseHandle(m_hStopRequest);
+ CloseHandle(m_hStarted);
+ CloseHandle(m_hBufferSwitch[1]);
+ CloseHandle(m_hBufferSwitch[0]);
+ }
+
+ BufferSwitchDispatcherBase(const BufferSwitchDispatcherBase &) noexcept = delete;
+ BufferSwitchDispatcherBase & operator=(const BufferSwitchDispatcherBase &) noexcept = delete;
+
+private:
+ static DWORD WINAPI ThreadProc(LPVOID lpParameter) noexcept {
+ if (!lpParameter) {
+ return 1;
+ }
+ return static_cast<BufferSwitchDispatcherBase *>(lpParameter)->ThreadMain() ? 0 : 1;
+ }
+
+ [[nodiscard]] bool ThreadMain() noexcept {
+ DWORD task_idx = 0;
+ HANDLE hTask = AvSetMmThreadCharacteristics(TEXT("Pro Audio"), &task_idx);
+ SetEvent(m_hStarted);
+ bool result = ThreadLoop();
+ if (hTask) {
+ AvRevertMmThreadCharacteristics(hTask);
+ }
+ hTask = NULL;
+ task_idx = 0;
+ return result;
+ }
+
+ [[nodiscard]] bool ThreadLoop() noexcept {
+ bool stop = false;
+ while (!stop) {
+ HANDLE events[3] = {m_hBufferSwitch[0], m_hBufferSwitch[1], m_hStopRequest};
+ switch (WaitForMultipleObjects(3, events, FALSE, INFINITE)) {
+ case WAIT_OBJECT_0 + 0:
+ CallFunc(0);
+ break;
+ case WAIT_OBJECT_0 + 1:
+ CallFunc(1);
+ break;
+ case WAIT_OBJECT_0 + 2:
+ stop = true;
+ break;
+ default:
+ return false;
+ break;
+ }
+ }
+ return true;
+ }
+
+protected:
+ virtual void CallFunc(std::size_t bufferIndex) = 0;
+
+public:
+ void Dispatch(std::size_t bufferIndex) final {
+ if (SetEvent(m_hBufferSwitch[bufferIndex & 1u]) != TRUE) {
+ throw std::bad_alloc();
+ }
+ }
+};
+
+template <typename Tfunc>
+class BufferSwitchDispatcher
+ : public BufferSwitchDispatcherBase {
+
+private:
+ Tfunc m_func;
+
+public:
+ BufferSwitchDispatcher(Tfunc func)
+ : m_func(func) {
+ return;
+ }
+
+protected:
+ void CallFunc(std::size_t bufferIndex) final {
+ m_func(bufferIndex);
+ }
+};
+
+template <typename Tfunc>
+inline std::unique_ptr<IBufferSwitchDispatcher> CreateBufferSwitchDispatcher(Tfunc func) {
+ return std::make_unique<BufferSwitchDispatcher<Tfunc>>(func);
+}
+
+
+
+#if defined(UNICODE)
+} // namespace Unicode
+#else
+} // namespace Ansi
+#endif
+
+
+
+} // namespace ASIO_VERSION_NAMESPACE
+
+
+
+} // namespace Windows
+
+
+
+#endif // ASIO_SYSTEM_WINDOWS
+
+
+
+} // namespace ASIO
+
+
+
+#endif // ASIO_ASIOSYSTEMWINDOWS_HPP
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSystemWindowsSEH.hpp b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSystemWindowsSEH.hpp
new file mode 100644
index 00000000..e36e61bc
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSystemWindowsSEH.hpp
@@ -0,0 +1,283 @@
+
+#ifndef ASIO_ASIOSYSTEMWINDOWSSEH_HPP
+#define ASIO_ASIOSYSTEMWINDOWSSEH_HPP
+
+
+
+#include "ASIOVersion.hpp"
+#include "ASIOConfig.hpp"
+#include "ASIOCore.hpp"
+#include "ASIOSystemWindows.hpp"
+
+#include <memory>
+#include <string_view>
+
+#include <cassert>
+
+#if ASIO_SYSTEM_WINDOWS
+#include <windows.h>
+#if !defined(NTDDI_VERSION)
+#error "NTDDI_VERSION undefined"
+#endif
+#if !defined(_WIN32_WINNT)
+#error "_WIN32_WINNT undefined"
+#endif
+#endif // ASIO_SYSTEM_WINDOWS
+
+
+
+namespace ASIO {
+
+
+
+#if ASIO_SYSTEM_WINDOWS
+
+
+
+namespace Windows {
+
+
+
+inline namespace ASIO_VERSION_NAMESPACE {
+
+
+
+static_assert(NTDDI_VERSION >= NTDDI_WIN7);
+static_assert(_WIN32_WINNT >= _WIN32_WINNT_WIN7);
+
+
+
+#if defined(UNICODE)
+inline namespace Unicode {
+#else
+inline namespace Ansi {
+#endif
+
+
+
+namespace SEH {
+
+struct DriverCrash {
+private:
+ DWORD m_Code;
+ std::string_view m_Func;
+
+public:
+ explicit constexpr DriverCrash(DWORD code, std::string_view func) noexcept
+ : m_Code(code)
+ , m_Func(func) {
+ return;
+ }
+
+public:
+ constexpr DWORD code() const noexcept {
+ return m_Code;
+ }
+ constexpr std::string_view func() const noexcept {
+ return m_Func;
+ }
+};
+
+class IState {
+protected:
+ IState() noexcept = default;
+
+public:
+ IState(const IState &) = delete;
+ IState & operator=(const IState &) = delete;
+
+public:
+ virtual ~IState() = default;
+};
+
+class ITranslator {
+protected:
+ ITranslator() noexcept = default;
+
+public:
+ ITranslator(const ITranslator &) = delete;
+ ITranslator & operator=(const ITranslator &) = delete;
+
+public:
+ virtual ~ITranslator() = default;
+
+public:
+ [[nodiscard]] virtual LONG TranslatorFilter(std::unique_ptr<IState> & state, DWORD code, LPEXCEPTION_POINTERS records, std::string_view func) const noexcept = 0;
+ [[noreturn]] virtual void TranslatorHandler(std::unique_ptr<IState> & state, DWORD code, std::string_view func) const = 0;
+};
+
+class DefaultTranslator
+ : public ITranslator {
+public:
+ virtual ~DefaultTranslator() = default;
+
+public:
+ [[nodiscard]] LONG TranslatorFilter(std::unique_ptr<IState> & /* state */, DWORD /* code */, LPEXCEPTION_POINTERS /* records */, std::string_view /* func */) const noexcept final {
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+ [[noreturn]] void TranslatorHandler(std::unique_ptr<IState> & /* state */, DWORD code, std::string_view func) const final {
+ throw DriverCrash(code, func);
+ }
+};
+
+class Driver
+ : public IDriver {
+
+private:
+ ISystemDriver * m_Driver = nullptr;
+ std::unique_ptr<ITranslator> m_Translator = nullptr;
+
+private:
+ template <typename Tfn>
+ static auto TranslateSEtry(std::unique_ptr<ITranslator> & translator, std::unique_ptr<IState> & state, Tfn fn, std::string_view func) -> decltype(fn()) {
+ __try
+ {
+ return fn();
+ } __except (translator->TranslatorFilter(state, GetExceptionCode(), GetExceptionInformation(), func))
+ {
+ translator->TranslatorHandler(state, GetExceptionCode(), func);
+ }
+ throw DriverCrash(0, func);
+ }
+
+ template <typename Tfn>
+ auto TranslateSE(Tfn fn, std::string_view func) -> decltype(fn()) {
+ assert(m_Translator);
+ std::unique_ptr<IState> state;
+ return TranslateSEtry(m_Translator, state, fn, func);
+ }
+
+ template <typename Tfn>
+ auto CallDriver(Tfn fn, std::string_view func) -> decltype(fn()) {
+ return TranslateSE(fn, func);
+ }
+
+public:
+ explicit Driver(CLSID clsid, HWND wnd, std::unique_ptr<ITranslator> translator = std::make_unique<DefaultTranslator>())
+ : m_Translator(std::move(translator)) {
+ m_Driver = openDriver(clsid);
+ if (!m_Driver) {
+ throw DriverLoadFailed();
+ }
+ if (!initDriver(wnd)) {
+ closeDriver(m_Driver);
+ throw DriverInitFailed();
+ }
+ }
+
+ Driver(const Driver &) = delete;
+
+ Driver & operator=(const Driver &) = delete;
+
+ ~Driver() noexcept(false) override {
+ closeDriver(m_Driver);
+ }
+
+private:
+ ISystemDriver * openDriver(CLSID clsid) {
+ return CallDriver([&]() { return OpenDriver(clsid); }, __func__);
+ }
+
+ ULONG closeDriver(ISystemDriver * driver) {
+ return CallDriver([&]() { return CloseDriver(driver); }, __func__);
+ }
+
+private:
+ Bool initDriver(HWND sysHandle) {
+ return static_cast<Bool>(CallDriver([&]() { return m_Driver->init(reinterpret_cast<SysHandle>(sysHandle)); }, __func__));
+ }
+
+public:
+ void getDriverName(DriverName * name) final {
+ return CallDriver([&]() { return m_Driver->getDriverName(name); }, __func__);
+ }
+ [[nodiscard]] Long getDriverVersion() final {
+ return CallDriver([&]() { return m_Driver->getDriverVersion(); }, __func__);
+ }
+ void getErrorMessage(ErrorMessage * string) final {
+ return CallDriver([&]() { return m_Driver->getErrorMessage(string); }, __func__);
+ }
+ [[nodiscard]] ErrorCode start() final {
+ return CallDriver([&]() { return m_Driver->start(); }, __func__);
+ }
+ [[nodiscard]] ErrorCode stop() final {
+ return CallDriver([&]() { return m_Driver->stop(); }, __func__);
+ }
+ [[nodiscard]] ErrorCode getChannels(Long * numInputChannels, Long * numOutputChannels) final {
+ return CallDriver([&]() { return m_Driver->getChannels(numInputChannels, numOutputChannels); }, __func__);
+ }
+ [[nodiscard]] ErrorCode getLatencies(Long * inputLatency, Long * outputLatency) final {
+ return CallDriver([&]() { return m_Driver->getLatencies(inputLatency, outputLatency); }, __func__);
+ }
+ [[nodiscard]] ErrorCode getBufferSize(Long * minSize, Long * maxSize, Long * preferredSize, Long * granularity) final {
+ return CallDriver([&]() { return m_Driver->getBufferSize(minSize, maxSize, preferredSize, granularity); }, __func__);
+ }
+ [[nodiscard]] ErrorCode canSampleRate(SampleRate sampleRate) final {
+ return CallDriver([&]() { return m_Driver->canSampleRate(sampleRate); }, __func__);
+ }
+ [[nodiscard]] ErrorCode getSampleRate(SampleRate * sampleRate) final {
+ return CallDriver([&]() { return m_Driver->getSampleRate(sampleRate); }, __func__);
+ }
+ [[nodiscard]] ErrorCode setSampleRate(SampleRate sampleRate) final {
+ return CallDriver([&]() { return m_Driver->setSampleRate(sampleRate); }, __func__);
+ }
+ [[nodiscard]] ErrorCode getClockSources(ClockSource * clocks, Long * numSources) final {
+ return CallDriver([&]() { return m_Driver->getClockSources(clocks, numSources); }, __func__);
+ }
+ [[nodiscard]] ErrorCode setClockSource(Long reference) final {
+ return CallDriver([&]() { return m_Driver->setClockSource(reference); }, __func__);
+ }
+ [[nodiscard]] ErrorCode getSamplePosition(HiLoLongLong * samplePosition, HiLoLongLong * timeStamp) final {
+ return CallDriver([&]() { return m_Driver->getSamplePosition(samplePosition, timeStamp); }, __func__);
+ }
+ [[nodiscard]] ErrorCode getChannelInfo(ChannelInfo * info) final {
+ return CallDriver([&]() { return m_Driver->getChannelInfo(info); }, __func__);
+ }
+ [[nodiscard]] ErrorCode createBuffers(BufferInfo * bufferInfos, Long numChannels, Long bufferSize, Callbacks const * callbacks) final {
+ return CallDriver([&]() { return m_Driver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks); }, __func__);
+ }
+ [[nodiscard]] ErrorCode disposeBuffers() final {
+ return CallDriver([&]() { return m_Driver->disposeBuffers(); }, __func__);
+ }
+ [[nodiscard]] ErrorCode controlPanel() final {
+ return CallDriver([&]() { return m_Driver->controlPanel(); }, __func__);
+ }
+ [[nodiscard]] ErrorCode future(FutureSelector selector, void * opt) final {
+ return CallDriver([&]() { return m_Driver->future(selector, opt); }, __func__);
+ }
+ [[nodiscard]] ErrorCode outputReady() final {
+ return CallDriver([&]() { return m_Driver->outputReady(); }, __func__);
+ }
+};
+
+
+
+} // namespace SEH
+
+
+
+#if defined(UNICODE)
+} // namespace Unicode
+#else
+} // namespace Ansi
+#endif
+
+
+
+} // namespace ASIO_VERSION_NAMESPACE
+
+
+
+} // namespace Windows
+
+
+
+#endif // ASIO_SYSTEM_WINDOWS
+
+
+
+} // namespace ASIO
+
+
+
+#endif // ASIO_ASIOSYSTEMWINDOWS_HPP
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVerifyABI.hpp b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVerifyABI.hpp
new file mode 100644
index 00000000..94df6e56
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVerifyABI.hpp
@@ -0,0 +1,127 @@
+
+#ifndef ASIO_ASIOVERIFY_ABI_HPP
+#define ASIO_ASIOVERIFY_ABI_HPP
+
+
+
+#include "ASIOVersion.hpp"
+#include "ASIOConfig.hpp"
+#include "ASIOCore.hpp"
+
+#if __has_include(<iasiodrv.h>)
+#define ASIO_ABI_VERIFIED 1
+#include <iasiodrv.h>
+#else
+#define ASIO_ABI_VERIFIED 0
+ASIO_WARNING("Warning: iasiodrv.h not found. ASIO ABI is not verified.")
+#endif
+
+
+
+namespace ASIO {
+
+
+
+#if ASIO_ABI_VERIFIED
+
+inline namespace VerifyABI {
+
+
+
+inline namespace ASIO_VERSION_NAMESPACE {
+
+
+
+static_assert(sizeof(ASIO::SysHandle) == sizeof(void *));
+static_assert(sizeof(ASIO::Byte) == sizeof(char));
+static_assert(sizeof(ASIO::Long) == sizeof(long));
+static_assert(sizeof(ASIO::ULong) == sizeof(unsigned long));
+static_assert(sizeof(ASIO::ULongLong) == sizeof(unsigned long long int));
+static_assert(sizeof(ASIO::Double) == sizeof(double));
+static_assert(sizeof(ASIO::Char) == sizeof(char));
+static_assert(sizeof(ASIO::Padding1) == sizeof(char));
+static_assert(sizeof(ASIO::PaddingLong) == sizeof(long));
+static_assert(sizeof(ASIO::Bool) == sizeof(long));
+static_assert(sizeof(ASIO::HiLoLongLong) == sizeof(long long int));
+static_assert(sizeof(ASIO::ResultBool) == sizeof(long));
+static_assert(sizeof(ASIO::CharBuf<1>) == sizeof(char[1]));
+static_assert(sizeof(ASIO::Samples) == sizeof(::ASIOSamples));
+static_assert(sizeof(ASIO::TimeStamp) == sizeof(::ASIOTimeStamp));
+static_assert(sizeof(ASIO::SampleRate) == sizeof(::ASIOSampleRate));
+static_assert(sizeof(ASIO::SampleType) == sizeof(::ASIOSampleType));
+static_assert(sizeof(ASIO::ErrorCode) == sizeof(::ASIOError));
+static_assert(sizeof(ASIO::TimeCodeFlags) == sizeof(::ASIOTimeCodeFlags));
+static_assert(sizeof(ASIO::TimeCode) == sizeof(::ASIOTimeCode));
+static_assert(sizeof(ASIO::TimeInfoFlags) == sizeof(::AsioTimeInfoFlags));
+static_assert(sizeof(ASIO::TimeInfo) == sizeof(::AsioTimeInfo));
+static_assert(sizeof(ASIO::Time) == sizeof(::ASIOTime));
+static_assert(sizeof(ASIO::MessageSelector) == sizeof(long));
+static_assert(sizeof(ASIO::Callbacks) == sizeof(::ASIOCallbacks));
+static_assert(sizeof(ASIO::ClockSource) == sizeof(::ASIOClockSource));
+static_assert(sizeof(ASIO::ChannelInfo) == sizeof(::ASIOChannelInfo));
+static_assert(sizeof(ASIO::BufferInfo) == sizeof(::ASIOBufferInfo));
+static_assert(sizeof(ASIO::FutureSelector) == sizeof(long));
+static_assert(sizeof(ASIO::InputMonitor) == sizeof(::ASIOInputMonitor));
+static_assert(sizeof(ASIO::ChannelControls) == sizeof(::ASIOChannelControls));
+static_assert(sizeof(ASIO::TransportCommand) == sizeof(long));
+static_assert(sizeof(ASIO::TransportParameters) == sizeof(::ASIOTransportParameters));
+static_assert(sizeof(ASIO::IoFormatType) == sizeof(::ASIOIoFormatType));
+static_assert(sizeof(ASIO::IoFormat) == sizeof(::ASIOIoFormat));
+static_assert(sizeof(ASIO::InternalBufferInfo) == sizeof(::ASIOInternalBufferInfo));
+static_assert(sizeof(ASIO::ISystemDriver) == sizeof(::IASIO));
+
+static_assert(alignof(ASIO::SysHandle) == alignof(void *));
+static_assert(alignof(ASIO::Byte) == alignof(char));
+static_assert(alignof(ASIO::Long) == alignof(long));
+static_assert(alignof(ASIO::ULong) == alignof(unsigned long));
+static_assert(alignof(ASIO::ULongLong) == alignof(unsigned long long int));
+static_assert(alignof(ASIO::Double) == alignof(double));
+static_assert(alignof(ASIO::Char) == alignof(char));
+static_assert(alignof(ASIO::Padding1) == alignof(char));
+static_assert(alignof(ASIO::PaddingLong) == alignof(long));
+static_assert(alignof(ASIO::Bool) == alignof(long));
+static_assert((NATIVE_INT64 && (alignof(ASIO::HiLoLongLong) == alignof(long long int))) || (!NATIVE_INT64 && (alignof(ASIO::HiLoLongLong) == alignof(unsigned long[2]))));
+static_assert(alignof(ASIO::ResultBool) == alignof(long));
+static_assert(alignof(ASIO::CharBuf<1>) == alignof(char[1]));
+static_assert(alignof(ASIO::Samples) == alignof(::ASIOSamples));
+static_assert(alignof(ASIO::TimeStamp) == alignof(::ASIOTimeStamp));
+static_assert(alignof(ASIO::SampleRate) == alignof(::ASIOSampleRate));
+static_assert(alignof(ASIO::SampleType) == alignof(::ASIOSampleType));
+static_assert(alignof(ASIO::ErrorCode) == alignof(::ASIOError));
+static_assert(alignof(ASIO::TimeCodeFlags) == alignof(::ASIOTimeCodeFlags));
+static_assert(alignof(ASIO::TimeCode) == alignof(::ASIOTimeCode));
+static_assert(alignof(ASIO::TimeInfoFlags) == alignof(::AsioTimeInfoFlags));
+static_assert(alignof(ASIO::TimeInfo) == alignof(::AsioTimeInfo));
+static_assert(alignof(ASIO::Time) == alignof(::ASIOTime));
+static_assert(alignof(ASIO::MessageSelector) == alignof(long));
+static_assert(alignof(ASIO::Callbacks) == alignof(::ASIOCallbacks));
+static_assert(alignof(ASIO::ClockSource) == alignof(::ASIOClockSource));
+static_assert(alignof(ASIO::ChannelInfo) == alignof(::ASIOChannelInfo));
+static_assert(alignof(ASIO::BufferInfo) == alignof(::ASIOBufferInfo));
+static_assert(alignof(ASIO::FutureSelector) == alignof(long));
+static_assert(alignof(ASIO::InputMonitor) == alignof(::ASIOInputMonitor));
+static_assert(alignof(ASIO::ChannelControls) == alignof(::ASIOChannelControls));
+static_assert(alignof(ASIO::TransportCommand) == alignof(long));
+static_assert(alignof(ASIO::TransportParameters) == alignof(::ASIOTransportParameters));
+static_assert(alignof(ASIO::IoFormatType) == alignof(::ASIOIoFormatType));
+static_assert(alignof(ASIO::IoFormat) == alignof(::ASIOIoFormat));
+static_assert(alignof(ASIO::InternalBufferInfo) == alignof(::ASIOInternalBufferInfo));
+static_assert(alignof(ASIO::ISystemDriver) == alignof(::IASIO));
+
+
+
+} // namespace ASIO_VERSION_NAMESPACE
+
+
+
+} // namespace VerifyABI
+
+#endif // ASIO_ABI_VERIFIED
+
+
+
+} // namespace ASIO
+
+
+
+#endif // ASIO_ASIOVERIFY_ABI_HPP
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVersion.hpp b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVersion.hpp
new file mode 100644
index 00000000..02fd4fe7
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVersion.hpp
@@ -0,0 +1,132 @@
+
+#ifndef ASIO_ASIOVERSION_HPP
+#define ASIO_ASIOVERSION_HPP
+
+
+
+namespace ASIO {
+
+
+
+#define ASIO_VERSION_MAJOR 2
+#define ASIO_VERSION_MINOR 3
+#define ASIO_VERSION_PATCH 3
+#define ASIO_VERSION_BUILD 20190614
+
+
+
+#define ASIO_MODERNSDK_VERSION_MAJOR 0
+#define ASIO_MODERNSDK_VERSION_MINOR 12
+#define ASIO_MODERNSDK_VERSION_PATCH 5
+#define ASIO_MODERNSDK_VERSION_BUILD 0
+
+
+
+#define ASIO_VERSION_BUILD_NAMESPACE_IMPL(a, b, c, d) v##a##_##b##_##c
+#define ASIO_VERSION_BUILD_NAMESPACE(a, b, c, d) ASIO_VERSION_BUILD_NAMESPACE_IMPL(a, b, c, d)
+
+
+
+#define ASIO_VERSION_NAMESPACE ASIO_VERSION_BUILD_NAMESPACE(ASIO_MODERNSDK_VERSION_MAJOR, ASIO_MODERNSDK_VERSION_MINOR, ASIO_MODERNSDK_VERSION_PATCH, ASIO_MODERNSDK_VERSION_BUILD)
+
+
+
+inline namespace Version {
+
+
+
+inline namespace ASIO_VERSION_NAMESPACE {
+
+
+
+struct SemanticVersion {
+ unsigned long long Major = 0;
+ unsigned long long Minor = 0;
+ unsigned long long Patch = 0;
+ constexpr std::tuple<unsigned long long, unsigned long long, unsigned long long> as_tuple() const noexcept {
+ return std::make_tuple(Major, Minor, Patch);
+ }
+};
+
+constexpr bool operator==(SemanticVersion a, SemanticVersion b) noexcept {
+ return a.as_tuple() == b.as_tuple();
+}
+constexpr bool operator!=(SemanticVersion a, SemanticVersion b) noexcept {
+ return a.as_tuple() != b.as_tuple();
+}
+constexpr bool operator<(SemanticVersion a, SemanticVersion b) noexcept {
+ return a.as_tuple() < b.as_tuple();
+}
+constexpr bool operator>(SemanticVersion a, SemanticVersion b) noexcept {
+ return a.as_tuple() > b.as_tuple();
+}
+constexpr bool operator<=(SemanticVersion a, SemanticVersion b) noexcept {
+ return a.as_tuple() <= b.as_tuple();
+}
+constexpr bool operator>=(SemanticVersion a, SemanticVersion b) noexcept {
+ return a.as_tuple() >= b.as_tuple();
+}
+
+struct VersionInfo {
+ SemanticVersion SemVer;
+ unsigned long long Build = 0;
+ constexpr std::tuple<std::tuple<unsigned long long, unsigned long long, unsigned long long>, unsigned long long> as_tuple() const noexcept {
+ return std::make_tuple(SemVer.as_tuple(), Build);
+ }
+ template <typename Tostream>
+ friend Tostream & operator<<(Tostream & os, VersionInfo vi) {
+ if (vi.Build > 0) {
+ os << vi.SemVer.Major << "." << vi.SemVer.Minor << "." << vi.SemVer.Patch << "+build." << vi.Build;
+ } else {
+ os << vi.SemVer.Major << "." << vi.SemVer.Minor << "." << vi.SemVer.Patch;
+ }
+ return os;
+ }
+};
+
+constexpr bool operator==(VersionInfo a, VersionInfo b) noexcept {
+ return a.as_tuple() == b.as_tuple();
+}
+constexpr bool operator!=(VersionInfo a, VersionInfo b) noexcept {
+ return a.as_tuple() != b.as_tuple();
+}
+constexpr bool operator<(VersionInfo a, VersionInfo b) noexcept {
+ return a.as_tuple() < b.as_tuple();
+}
+constexpr bool operator>(VersionInfo a, VersionInfo b) noexcept {
+ return a.as_tuple() > b.as_tuple();
+}
+constexpr bool operator<=(VersionInfo a, VersionInfo b) noexcept {
+ return a.as_tuple() <= b.as_tuple();
+}
+constexpr bool operator>=(VersionInfo a, VersionInfo b) noexcept {
+ return a.as_tuple() >= b.as_tuple();
+}
+
+
+
+constexpr inline VersionInfo Version = {
+ {ASIO_VERSION_MAJOR, ASIO_VERSION_MINOR, ASIO_VERSION_PATCH},
+ ASIO_VERSION_BUILD
+};
+
+constexpr inline VersionInfo ModernSDKVersion = {
+ {ASIO_MODERNSDK_VERSION_MAJOR, ASIO_MODERNSDK_VERSION_MINOR, ASIO_MODERNSDK_VERSION_PATCH},
+ ASIO_MODERNSDK_VERSION_BUILD
+};
+
+
+
+} // namespace ASIO_VERSION_NAMESPACE
+
+
+
+} // namespace Version
+
+
+
+} // namespace ASIO
+
+
+
+#endif // ASIO_ASIOVERSION_HPP
diff --git a/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOstdcxx20bit.hpp b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOstdcxx20bit.hpp
new file mode 100644
index 00000000..7b401ba9
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOstdcxx20bit.hpp
@@ -0,0 +1,48 @@
+
+#ifndef ASIO_ASIOSTDCXX20BIT_HPP
+#define ASIO_ASIOSTDCXX20BIT_HPP
+
+
+
+#include "ASIOVersion.hpp"
+#include "ASIOConfig.hpp"
+
+
+
+#if (__cplusplus > 202000L)
+#include <bit>
+namespace ASIO {
+namespace stdcxx20 {
+using std::bit_cast;
+using std::endian;
+} // namespace stdcxx20
+} // namespace ASIO
+#else // !C++20
+#include <type_traits>
+#include <cstring>
+namespace ASIO {
+namespace stdcxx20 {
+template <class To, class From>
+typename std::enable_if<(sizeof(To) == sizeof(From)) && std::is_trivially_copyable<From>::value && std::is_trivial<To>::value, To>::type inline bit_cast(const From & src) noexcept {
+ To dst;
+ std::memcpy(&dst, &src, sizeof(To));
+ return dst;
+}
+enum class endian {
+#if ASIO_SYSTEM_WINDOWS
+ little = 0,
+ big = 1,
+ native = little,
+#elif ASIO_COMPILER_CLANG || ASIO_COMPILER_GCC
+ little = __ORDER_LITTLE_ENDIAN__,
+ big = __ORDER_BIG_ENDIAN__,
+ native = __BYTE_ORDER__,
+#endif
+};
+} // namespace stdcxx20
+} // namespace ASIO
+#endif // C++20
+
+
+
+#endif // ASIO_ASIOSTDCXX20BIT_HPP