Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
1
Src/external_dependencies/openmpt-trunk/include/asiomodern/OpenMPT.txt
vendored
Normal file
1
Src/external_dependencies/openmpt-trunk/include/asiomodern/OpenMPT.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
ASIO::Modern v0.12.5
|
153
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/.clang-format
vendored
Normal file
153
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/.clang-format
vendored
Normal file
|
@ -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
|
16
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIO.hpp
vendored
Normal file
16
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIO.hpp
vendored
Normal file
|
@ -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
|
385
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOConfig.hpp
vendored
Normal file
385
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOConfig.hpp
vendored
Normal file
|
@ -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
|
469
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOCore.hpp
vendored
Normal file
469
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOCore.hpp
vendored
Normal file
|
@ -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
|
960
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOModern.hpp
vendored
Normal file
960
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOModern.hpp
vendored
Normal file
|
@ -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
|
1100
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSampleConvert.hpp
vendored
Normal file
1100
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSampleConvert.hpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
511
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSystemWindows.hpp
vendored
Normal file
511
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSystemWindows.hpp
vendored
Normal file
|
@ -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
|
|
@ -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
|
127
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVerifyABI.hpp
vendored
Normal file
127
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVerifyABI.hpp
vendored
Normal file
|
@ -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
|
132
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVersion.hpp
vendored
Normal file
132
Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOVersion.hpp
vendored
Normal file
|
@ -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
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue