winamp/Src/external_dependencies/openmpt-trunk/include/asiomodern/include/ASIOModern/ASIOSampleConvert.hpp

1100 lines
37 KiB
C++

#ifndef ASIO_ASIOSAMPLECONVERT_HPP
#define ASIO_ASIOSAMPLECONVERT_HPP
#include "ASIOVersion.hpp"
#include "ASIOConfig.hpp"
#include "ASIOCore.hpp"
#include <algorithm>
#include <array>
#include <limits>
#include <type_traits>
#include "ASIOstdcxx20bit.hpp"
#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstdint>
namespace ASIO {
namespace Sample {
inline namespace ASIO_VERSION_NAMESPACE {
namespace detail {
template <typename Type>
struct TraitsExternal { };
template <>
struct TraitsExternal<std::int8_t> {
using type = std::int8_t;
using internal_type = std::int64_t;
static constexpr internal_type scale = static_cast<internal_type>(1) << 24;
};
template <>
struct TraitsExternal<std::int16_t> {
using type = std::int16_t;
using internal_type = std::int64_t;
static constexpr internal_type scale = static_cast<internal_type>(1) << 16;
};
template <>
struct TraitsExternal<std::int32_t> {
using type = std::int32_t;
using internal_type = std::int64_t;
static constexpr internal_type scale = static_cast<internal_type>(1) << 0;
};
template <>
struct TraitsExternal<float> {
using type = float;
using internal_type = float;
};
template <>
struct TraitsExternal<double> {
using type = double;
using internal_type = double;
};
template <>
struct TraitsExternal<long double> {
using type = long double;
using internal_type = double;
};
struct Int16MSB {
std::array<std::byte, 2> data;
};
struct Int24MSB {
std::array<std::byte, 3> data;
};
struct Int32MSB {
std::array<std::byte, 4> data;
};
struct Int32MSB16 {
std::array<std::byte, 4> data;
};
struct Int32MSB18 {
std::array<std::byte, 4> data;
};
struct Int32MSB20 {
std::array<std::byte, 4> data;
};
struct Int32MSB24 {
std::array<std::byte, 4> data;
};
struct Float32MSB {
std::array<std::byte, 4> data;
};
struct Float64MSB {
std::array<std::byte, 8> data;
};
struct Int16LSB {
std::array<std::byte, 2> data;
};
struct Int24LSB {
std::array<std::byte, 3> data;
};
struct Int32LSB {
std::array<std::byte, 4> data;
};
struct Int32LSB16 {
std::array<std::byte, 4> data;
};
struct Int32LSB18 {
std::array<std::byte, 4> data;
};
struct Int32LSB20 {
std::array<std::byte, 4> data;
};
struct Int32LSB24 {
std::array<std::byte, 4> data;
};
struct Float32LSB {
std::array<std::byte, 4> data;
};
struct Float64LSB {
std::array<std::byte, 8> data;
};
template <typename Type>
struct Types { };
template <>
struct Types<detail::Int16MSB> {
using type = detail::Int16MSB;
static constexpr SampleType sample_type = SampleType::Int16MSB;
using internal_type = std::int64_t;
using value_type = std::int16_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 16;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = true;
};
template <>
struct Types<detail::Int24MSB> {
using type = detail::Int24MSB;
static constexpr SampleType sample_type = SampleType::Int24MSB;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 24;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = true;
};
template <>
struct Types<detail::Int32MSB> {
using type = detail::Int32MSB;
static constexpr SampleType sample_type = SampleType::Int32MSB;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 32;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = true;
};
template <>
struct Types<detail::Int32MSB16> {
using type = detail::Int32MSB16;
static constexpr SampleType sample_type = SampleType::Int32MSB16;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 16;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = true;
};
template <>
struct Types<detail::Int32MSB18> {
using type = detail::Int32MSB18;
static constexpr SampleType sample_type = SampleType::Int32MSB18;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 18;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = true;
};
template <>
struct Types<detail::Int32MSB20> {
using type = detail::Int32MSB20;
static constexpr SampleType sample_type = SampleType::Int32MSB20;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 20;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = true;
};
template <>
struct Types<detail::Int32MSB24> {
using type = detail::Int32MSB24;
static constexpr SampleType sample_type = SampleType::Int32MSB24;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 24;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = true;
};
template <>
struct Types<detail::Float32MSB> {
using type = detail::Float32MSB;
static constexpr SampleType sample_type = SampleType::Float32MSB;
using internal_type = float;
using value_type = float;
using unsigned_type = float;
static constexpr std::size_t valid_bits = 32;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = true;
};
template <>
struct Types<detail::Float64MSB> {
using type = detail::Float64MSB;
static constexpr SampleType sample_type = SampleType::Float64MSB;
using internal_type = double;
using value_type = double;
using unsigned_type = double;
static constexpr std::size_t valid_bits = 64;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = true;
};
template <>
struct Types<detail::Int16LSB> {
using type = detail::Int16LSB;
static constexpr SampleType sample_type = SampleType::Int16MSB;
using internal_type = std::int64_t;
using value_type = std::int16_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 16;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = false;
};
template <>
struct Types<detail::Int24LSB> {
using type = detail::Int24LSB;
static constexpr SampleType sample_type = SampleType::Int24LSB;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 24;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = false;
};
template <>
struct Types<detail::Int32LSB> {
using type = detail::Int32LSB;
static constexpr SampleType sample_type = SampleType::Int32LSB;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 32;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = false;
};
template <>
struct Types<detail::Int32LSB16> {
using type = detail::Int32LSB16;
static constexpr SampleType sample_type = SampleType::Int32LSB16;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 16;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = false;
};
template <>
struct Types<detail::Int32LSB18> {
using type = detail::Int32LSB18;
static constexpr SampleType sample_type = SampleType::Int32LSB18;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 18;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = false;
};
template <>
struct Types<detail::Int32LSB20> {
using type = detail::Int32LSB20;
static constexpr SampleType sample_type = SampleType::Int32LSB20;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 20;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = false;
};
template <>
struct Types<detail::Int32LSB24> {
using type = detail::Int32LSB24;
static constexpr SampleType sample_type = SampleType::Int32LSB24;
using internal_type = std::int64_t;
using value_type = std::int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
static constexpr std::size_t valid_bits = 24;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = false;
};
template <>
struct Types<detail::Float32LSB> {
using type = detail::Float32LSB;
static constexpr SampleType sample_type = SampleType::Float32LSB;
using internal_type = float;
using value_type = float;
using unsigned_type = float;
static constexpr std::size_t valid_bits = 32;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = false;
};
template <>
struct Types<detail::Float64LSB> {
using type = detail::Float64LSB;
static constexpr SampleType sample_type = SampleType::Float64LSB;
using internal_type = double;
using value_type = double;
using unsigned_type = double;
static constexpr std::size_t valid_bits = 64;
static constexpr bool is_float = std::is_floating_point<value_type>::value;
static constexpr bool is_be = false;
};
template <typename T>
constexpr T clip(T x) noexcept = delete;
template <>
constexpr std::int64_t clip<std::int64_t>(std::int64_t q32) noexcept {
return std::clamp(q32, static_cast<std::int64_t>(std::numeric_limits<std::int32_t>::min()), static_cast<std::int64_t>(std::numeric_limits<std::int32_t>::max()));
}
template <>
constexpr double clip<double>(double dbl) noexcept {
return std::clamp(dbl, -1.0, 1.0);
}
template <>
constexpr float clip<float>(float flt) noexcept {
return std::clamp(flt, -1.0f, 1.0f);
}
template <typename Tdst, typename Tsrc>
inline Tdst convert_internal(Tsrc x) noexcept = delete;
template <>
inline std::int64_t convert_internal<std::int64_t, std::int64_t>(std::int64_t q32) noexcept {
return q32;
}
template <>
inline std::int64_t convert_internal<std::int64_t, double>(double dbl) noexcept {
return std::llround(dbl * static_cast<double>(1ll << 32));
}
template <>
inline std::int64_t convert_internal<std::int64_t, float>(float flt) noexcept {
return std::llround(flt * static_cast<float>(1ll << 32));
}
template <>
inline double convert_internal<double, std::int64_t>(std::int64_t q32) noexcept {
return static_cast<double>(q32) * (1.0 / static_cast<double>(1ll << 32));
}
template <>
inline double convert_internal<double, double>(double dbl) noexcept {
return dbl;
}
template <>
inline double convert_internal<double, float>(float flt) noexcept {
return static_cast<double>(flt);
}
template <>
inline float convert_internal<float, std::int64_t>(std::int64_t q32) noexcept {
return static_cast<float>(q32) * (1.0f / static_cast<float>(1ll << 32));
}
template <>
inline float convert_internal<float, double>(double dbl) noexcept {
return static_cast<float>(dbl);
}
template <>
inline float convert_internal<float, float>(float flt) noexcept {
return flt;
}
template <typename SampleType>
inline SampleType sample_from_value(typename Types<SampleType>::value_type val) noexcept {
if constexpr (Types<SampleType>::is_float) {
static_assert(sizeof(SampleType) == sizeof(typename Types<SampleType>::value_type));
static_assert((stdcxx20::endian::native == stdcxx20::endian::little) || (stdcxx20::endian::native == stdcxx20::endian::big));
SampleType result = stdcxx20::bit_cast<SampleType>(val);
if constexpr (Types<SampleType>::is_be) {
if constexpr (stdcxx20::endian::native == stdcxx20::endian::little) {
std::reverse(std::begin(result.data), std::end(result.data));
}
} else {
if constexpr (stdcxx20::endian::native == stdcxx20::endian::big) {
std::reverse(std::begin(result.data), std::end(result.data));
}
}
return result;
} else {
SampleType result{};
typename Types<SampleType>::unsigned_type uval = static_cast<typename Types<SampleType>::unsigned_type>(val);
for (std::size_t byte = 0; byte < sizeof(SampleType); ++byte) {
if constexpr (Types<SampleType>::is_be) {
result.data[sizeof(SampleType) - 1 - byte] = std::byte{static_cast<std::uint8_t>(uval)};
} else {
result.data[byte] = std::byte{static_cast<std::uint8_t>(uval)};
}
uval /= (1u << 8);
}
return result;
}
}
template <typename SampleType>
inline typename Types<SampleType>::value_type value_from_sample(SampleType smp) noexcept {
if constexpr (Types<SampleType>::is_float) {
static_assert(sizeof(SampleType) == sizeof(typename Types<SampleType>::value_type));
static_assert((stdcxx20::endian::native == stdcxx20::endian::little) || (stdcxx20::endian::native == stdcxx20::endian::big));
if constexpr (Types<SampleType>::is_be) {
if constexpr (stdcxx20::endian::native == stdcxx20::endian::little) {
std::reverse(std::begin(smp.data), std::end(smp.data));
}
} else {
if constexpr (stdcxx20::endian::native == stdcxx20::endian::big) {
std::reverse(std::begin(smp.data), std::end(smp.data));
}
}
return stdcxx20::bit_cast<typename Types<SampleType>::value_type>(smp.data);
} else {
typename Types<SampleType>::unsigned_type uval = 0;
for (std::size_t byte = 0; byte < sizeof(SampleType); ++byte) {
uval *= (1u << 8);
if constexpr (Types<SampleType>::is_be) {
uval |= std::to_integer<std::uint8_t>(smp.data[byte]);
} else {
uval |= std::to_integer<std::uint8_t>(smp.data[sizeof(SampleType) - 1 - byte]);
}
}
return static_cast<typename Types<SampleType>::value_type>(uval);
}
}
template <typename SampleType>
inline typename Types<SampleType>::value_type value_from_internal(typename Types<SampleType>::internal_type smp_int) noexcept {
if constexpr (Types<SampleType>::is_float) {
return static_cast<typename Types<SampleType>::value_type>(smp_int);
} else {
return static_cast<typename Types<SampleType>::value_type>(clip(smp_int) / (static_cast<typename Types<SampleType>::internal_type>(1) << (32 - Types<SampleType>::valid_bits)));
}
}
template <typename SampleType>
inline typename Types<SampleType>::internal_type internal_from_value(typename Types<SampleType>::value_type val) noexcept {
if constexpr (Types<SampleType>::is_float) {
return static_cast<typename Types<SampleType>::internal_type>(val);
} else {
return clip(static_cast<typename Types<SampleType>::internal_type>(val) * (static_cast<typename Types<SampleType>::internal_type>(1) << (32 - Types<SampleType>::valid_bits)));
}
}
template <typename ExternalType>
inline typename TraitsExternal<ExternalType>::internal_type internal_from_external(ExternalType x) noexcept {
static_assert(std::is_floating_point<typename TraitsExternal<ExternalType>::internal_type>::value == std::is_floating_point<ExternalType>::value);
if constexpr (std::is_floating_point<ExternalType>::value) {
return static_cast<typename TraitsExternal<ExternalType>::internal_type>(x);
} else {
return static_cast<typename TraitsExternal<ExternalType>::internal_type>(x) * TraitsExternal<ExternalType>::scale;
}
}
template <typename ExternalType>
inline ExternalType external_from_internal(typename TraitsExternal<ExternalType>::internal_type x) noexcept {
static_assert(std::is_floating_point<typename TraitsExternal<ExternalType>::internal_type>::value == std::is_floating_point<ExternalType>::value);
if constexpr (std::is_floating_point<ExternalType>::value) {
return static_cast<ExternalType>(x);
} else {
return static_cast<ExternalType>(clip(x) / TraitsExternal<ExternalType>::scale);
}
}
template <typename SampleType, typename ExternalType>
inline SampleType sample_from_external(ExternalType x) noexcept {
return sample_from_value<SampleType>(value_from_internal<SampleType>(convert_internal<typename Types<SampleType>::internal_type, typename TraitsExternal<ExternalType>::internal_type>(internal_from_external<ExternalType>(x))));
}
template <typename ExternalType, typename SampleType>
inline ExternalType external_from_sample(SampleType x) noexcept {
return external_from_internal<ExternalType>(convert_internal<typename TraitsExternal<ExternalType>::internal_type, typename Types<SampleType>::internal_type>(internal_from_value<SampleType>(value_from_sample<SampleType>(x))));
}
template <typename Tdst>
inline void ClearBuffer(Tdst * dst, std::size_t dst_stride, std::size_t count) noexcept {
for (std::size_t i = 0; i < count; ++i)
{
Tdst val{};
std::fill(val.data.begin(), val.data.end(), std::byte{0});
*dst = val;
dst += dst_stride;
}
}
template <typename Tdst, typename Tsrc, typename Tfunc>
inline void ConvertBuffer(Tdst * dst, std::size_t dst_stride, const Tsrc * src, std::size_t src_stride, std::size_t count, Tfunc func) noexcept(noexcept(func(Tsrc()))) {
for (std::size_t i = 0; i < count; ++i)
{
*dst = func(*src);
src += src_stride;
dst += dst_stride;
}
}
} // namespace detail
inline void ClearBufferASIO(void * dst, SampleType type, std::size_t count) noexcept {
switch (type) {
case SampleType::Int16MSB:
{
using SampleType = detail::Int16MSB;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int16LSB:
{
using SampleType = detail::Int16LSB;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int24MSB:
{
using SampleType = detail::Int24MSB;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int24LSB:
{
using SampleType = detail::Int24LSB;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int32MSB:
{
using SampleType = detail::Int32MSB;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int32LSB:
{
using SampleType = detail::Int32LSB;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Float32MSB:
{
using SampleType = detail::Float32MSB;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Float32LSB:
{
using SampleType = detail::Float32LSB;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Float64MSB:
{
using SampleType = detail::Float64MSB;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Float64LSB:
{
using SampleType = detail::Float64LSB;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int32MSB16:
{
using SampleType = detail::Int32MSB16;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int32LSB16:
{
using SampleType = detail::Int32LSB16;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int32MSB18:
{
using SampleType = detail::Int32MSB18;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int32LSB18:
{
using SampleType = detail::Int32LSB18;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int32MSB20:
{
using SampleType = detail::Int32MSB20;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int32LSB20:
{
using SampleType = detail::Int32LSB20;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int32MSB24:
{
using SampleType = detail::Int32MSB24;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
case SampleType::Int32LSB24:
{
using SampleType = detail::Int32LSB24;
detail::ClearBuffer(static_cast<SampleType *>(dst), 1, count);
}
break;
default:
assert(false);
break;
}
}
template <typename Tdst>
inline void CopyRawFromASIO(Tdst * dst, std::size_t dst_stride, const void * src, std::size_t count) noexcept {
detail::ConvertBuffer(dst, dst_stride, static_cast<const Tdst *>(src), 1, count, [](Tdst smp) { return smp; });
}
template <typename Tsrc>
inline void CopyRawToASIO(void * dst, const Tsrc * src, std::size_t src_stride, std::size_t count) noexcept {
detail::ConvertBuffer(static_cast<Tsrc *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return smp; });
}
template <typename Tdst>
inline void ConvertFromASIO(Tdst * dst, std::size_t dst_stride, SampleType type, const void * src, std::size_t count) noexcept {
switch (type) {
case SampleType::Int16MSB:
{
using SampleType = detail::Int16MSB;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int16LSB:
{
using SampleType = detail::Int16LSB;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int24MSB:
{
using SampleType = detail::Int24MSB;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int24LSB:
{
using SampleType = detail::Int24LSB;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int32MSB:
{
using SampleType = detail::Int32MSB;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int32LSB:
{
using SampleType = detail::Int32LSB;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Float32MSB:
{
using SampleType = detail::Float32MSB;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Float32LSB:
{
using SampleType = detail::Float32LSB;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Float64MSB:
{
using SampleType = detail::Float64MSB;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Float64LSB:
{
using SampleType = detail::Float64LSB;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int32MSB16:
{
using SampleType = detail::Int32MSB16;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int32LSB16:
{
using SampleType = detail::Int32LSB16;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int32MSB18:
{
using SampleType = detail::Int32MSB18;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int32LSB18:
{
using SampleType = detail::Int32LSB18;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int32MSB20:
{
using SampleType = detail::Int32MSB20;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int32LSB20:
{
using SampleType = detail::Int32LSB20;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int32MSB24:
{
using SampleType = detail::Int32MSB24;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
case SampleType::Int32LSB24:
{
using SampleType = detail::Int32LSB24;
detail::ConvertBuffer(dst, dst_stride, static_cast<const SampleType *>(src), 1, count, [](SampleType smp) { return detail::external_from_sample<Tdst, SampleType>(smp); });
}
break;
default:
assert(false);
break;
}
}
template <typename Tsrc>
inline void ConvertToASIO(void * dst, SampleType type, const Tsrc * src, std::size_t src_stride, std::size_t count) noexcept {
switch (type) {
case SampleType::Int16MSB:
{
using SampleType = detail::Int16MSB;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int16LSB:
{
using SampleType = detail::Int16LSB;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int24MSB:
{
using SampleType = detail::Int24MSB;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int24LSB:
{
using SampleType = detail::Int24LSB;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int32MSB:
{
using SampleType = detail::Int32MSB;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int32LSB:
{
using SampleType = detail::Int32LSB;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Float32MSB:
{
using SampleType = detail::Float32MSB;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Float32LSB:
{
using SampleType = detail::Float32LSB;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Float64MSB:
{
using SampleType = detail::Float64MSB;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Float64LSB:
{
using SampleType = detail::Float64LSB;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int32MSB16:
{
using SampleType = detail::Int32MSB16;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int32LSB16:
{
using SampleType = detail::Int32LSB16;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int32MSB18:
{
using SampleType = detail::Int32MSB18;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int32LSB18:
{
using SampleType = detail::Int32LSB18;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int32MSB20:
{
using SampleType = detail::Int32MSB20;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int32LSB20:
{
using SampleType = detail::Int32LSB20;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int32MSB24:
{
using SampleType = detail::Int32MSB24;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
case SampleType::Int32LSB24:
{
using SampleType = detail::Int32LSB24;
detail::ConvertBuffer(static_cast<SampleType *>(dst), 1, src, src_stride, count, [](Tsrc smp) { return detail::sample_from_external<SampleType, Tsrc>(smp); });
}
break;
default:
assert(false);
break;
}
}
struct Traits {
std::size_t size_bytes = 0;
std::size_t valid_bits = 0;
bool is_float = false;
bool is_be = false;
constexpr explicit Traits(SampleType type) noexcept {
switch (type) {
case SampleType::Int16MSB:
{
using Type = detail::Types<detail::Int16MSB>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int24MSB:
{
using Type = detail::Types<detail::Int24MSB>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int32MSB:
{
using Type = detail::Types<detail::Int32MSB>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Float32MSB:
{
using Type = detail::Types<detail::Float32MSB>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Float64MSB:
{
using Type = detail::Types<detail::Float64MSB>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int32MSB16:
{
using Type = detail::Types<detail::Int32MSB16>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int32MSB18:
{
using Type = detail::Types<detail::Int32MSB18>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int32MSB20:
{
using Type = detail::Types<detail::Int32MSB20>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int32MSB24:
{
using Type = detail::Types<detail::Int32MSB24>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int16LSB:
{
using Type = detail::Types<detail::Int16LSB>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int24LSB:
{
using Type = detail::Types<detail::Int24LSB>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int32LSB:
{
using Type = detail::Types<detail::Int32LSB>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Float32LSB:
{
using Type = detail::Types<detail::Float32LSB>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Float64LSB:
{
using Type = detail::Types<detail::Float64LSB>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int32LSB16:
{
using Type = detail::Types<detail::Int32LSB16>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int32LSB18:
{
using Type = detail::Types<detail::Int32LSB18>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int32LSB20:
{
using Type = detail::Types<detail::Int32LSB20>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
case SampleType::Int32LSB24:
{
using Type = detail::Types<detail::Int32LSB24>;
size_bytes = sizeof(Type::type);
valid_bits = Type::valid_bits;
is_float = Type::is_float;
is_be = Type::is_be;
}
break;
default:
break;
}
}
};
} // namespace ASIO_VERSION_NAMESPACE
} // namespace Sample
} // namespace ASIO
#endif // ASIO_ASIOSAMPLECONVERT_HPP