| 
							- #pragma once
 - #include <type_traits>
 - #include <dsp/common.hpp>
 - 
 - 
 - namespace rack {
 - namespace dsp {
 - 
 - 
 - /** 24-bit integer, using int32_t for conversions. */
 - struct
 - #ifdef __clang__
 - __attribute__((packed, aligned(1)))
 - #else
 - __attribute__((packed, aligned(1), gcc_struct))
 - #endif
 - Int24 {
 - 	int32_t i : 24;
 - 	Int24() {}
 - 	Int24(int32_t i) : i(i) {}
 - 	operator int32_t() {return i;}
 - };
 - static_assert(sizeof(Int24) == 3, "Int24 type must be 3 bytes");
 - 
 - 
 - /** Converts between normalized types.
 - */
 - template <typename To, typename From>
 - To convert(From x) = delete;
 - 
 - 
 - /** Trivial conversions */
 - template <>
 - inline float convert(float x) {return x;}
 - 
 - 
 - /** Integer to float */
 - template <>
 - inline float convert(int8_t x) {return x / 128.f;}
 - template <>
 - inline float convert(int16_t x) {return x / 32768.f;}
 - template <>
 - inline float convert(Int24 x) {return x / 8388608.f;}
 - template <>
 - inline float convert(int32_t x) {return x / 2147483648.f;}
 - template <>
 - inline float convert(int64_t x) {return x / 9223372036854775808.f;}
 - 
 - 
 - /** Float to integer */
 - template <>
 - inline int8_t convert(float x) {return std::min(std::llround(x * 128.f), 127LL);}
 - template <>
 - inline int16_t convert(float x) {return std::min(std::llround(x * 32768.f), 32767LL);}
 - template <>
 - inline Int24 convert(float x) {return std::min(std::llround(x * 8388608.f), 8388607LL);}
 - template <>
 - inline int32_t convert(float x) {return std::min(std::llround(x * 2147483648.f), 2147483647LL);}
 - template <>
 - inline int64_t convert(float x) {return std::min(std::llround(x * 9223372036854775808.f), 9223372036854775807LL);}
 - 
 - 
 - /** Buffer conversion */
 - template <typename To, typename From>
 - void convert(const From* in, To* out, size_t len) {
 - 	for (size_t i = 0; i < len; i++) {
 - 		out[i] = convert<To, From>(in[i]);
 - 	}
 - }
 - 
 - 
 - } // namespace dsp
 - } // namespace rack
 
 
  |