aboutsummaryrefslogtreecommitdiffstats
path: root/al/eax/utils.h
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-05-03 16:17:49 +0200
committerSven Gothel <[email protected]>2023-05-03 16:17:49 +0200
commitec167fd05661a5b02dd406c87081f84a0f8dd77d (patch)
tree9c4669e471c9969bda59265381b18d2d416db060 /al/eax/utils.h
parent0d14d30808cfe7b9e3413353e3eef8a0f201399a (diff)
parentd3875f333fb6abe2f39d82caca329414871ae53b (diff)
Merge branch 'v1.23.1'
Resolved Conflicts: CMakeLists.txt
Diffstat (limited to 'al/eax/utils.h')
-rw-r--r--al/eax/utils.h95
1 files changed, 95 insertions, 0 deletions
diff --git a/al/eax/utils.h b/al/eax/utils.h
new file mode 100644
index 00000000..8ff75a18
--- /dev/null
+++ b/al/eax/utils.h
@@ -0,0 +1,95 @@
+#ifndef EAX_UTILS_INCLUDED
+#define EAX_UTILS_INCLUDED
+
+#include <algorithm>
+#include <cstdint>
+#include <string>
+#include <type_traits>
+
+using EaxDirtyFlags = unsigned int;
+
+struct EaxAlLowPassParam {
+ float gain;
+ float gain_hf;
+};
+
+void eax_log_exception(const char *message) noexcept;
+
+template<typename TException, typename TValue>
+void eax_validate_range(
+ const char* value_name,
+ const TValue& value,
+ const TValue& min_value,
+ const TValue& max_value)
+{
+ if (value >= min_value && value <= max_value)
+ return;
+
+ const auto message =
+ std::string{value_name} +
+ " out of range (value: " +
+ std::to_string(value) + "; min: " +
+ std::to_string(min_value) + "; max: " +
+ std::to_string(max_value) + ").";
+
+ throw TException{message.c_str()};
+}
+
+namespace detail {
+
+template<typename T>
+struct EaxIsBitFieldStruct {
+private:
+ using yes = std::true_type;
+ using no = std::false_type;
+
+ template<typename U>
+ static auto test(int) -> decltype(std::declval<typename U::EaxIsBitFieldStruct>(), yes{});
+
+ template<typename>
+ static no test(...);
+
+public:
+ static constexpr auto value = std::is_same<decltype(test<T>(0)), yes>::value;
+};
+
+template<typename T, typename TValue>
+inline bool eax_bit_fields_are_equal(const T& lhs, const T& rhs) noexcept
+{
+ static_assert(sizeof(T) == sizeof(TValue), "Invalid type size.");
+ return reinterpret_cast<const TValue&>(lhs) == reinterpret_cast<const TValue&>(rhs);
+}
+
+} // namespace detail
+
+template<
+ typename T,
+ std::enable_if_t<detail::EaxIsBitFieldStruct<T>::value, int> = 0
+>
+inline bool operator==(const T& lhs, const T& rhs) noexcept
+{
+ using Value = std::conditional_t<
+ sizeof(T) == 1,
+ std::uint8_t,
+ std::conditional_t<
+ sizeof(T) == 2,
+ std::uint16_t,
+ std::conditional_t<
+ sizeof(T) == 4,
+ std::uint32_t,
+ void>>>;
+
+ static_assert(!std::is_same<Value, void>::value, "Unsupported type.");
+ return detail::eax_bit_fields_are_equal<T, Value>(lhs, rhs);
+}
+
+template<
+ typename T,
+ std::enable_if_t<detail::EaxIsBitFieldStruct<T>::value, int> = 0
+>
+inline bool operator!=(const T& lhs, const T& rhs) noexcept
+{
+ return !(lhs == rhs);
+}
+
+#endif // !EAX_UTILS_INCLUDED