You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

70 lines
1.7KB

  1. #pragma once
  2. #include <type_traits>
  3. #include <dsp/common.hpp>
  4. namespace rack {
  5. namespace dsp {
  6. /** 24-bit integer, using int32_t for conversions. */
  7. struct
  8. #ifdef __clang__
  9. __attribute__((packed, aligned(1)))
  10. #else
  11. __attribute__((packed, aligned(1), gcc_struct))
  12. #endif
  13. Int24 {
  14. int32_t i : 24;
  15. Int24() {}
  16. Int24(int32_t i) : i(i) {}
  17. operator int32_t() {return i;}
  18. };
  19. static_assert(sizeof(Int24) == 3, "Int24 type must be 3 bytes");
  20. /** Converts between normalized types.
  21. Default implementation is the default cast.
  22. */
  23. template <typename To, typename From>
  24. To convert(From x) {return x;}
  25. /** Integer to float */
  26. template <>
  27. inline float convert(int8_t x) {return x / 128.f;}
  28. template <>
  29. inline float convert(int16_t x) {return x / 32768.f;}
  30. template <>
  31. inline float convert(Int24 x) {return x / 8388608.f;}
  32. template <>
  33. inline float convert(int32_t x) {return x / 2147483648.f;}
  34. template <>
  35. inline float convert(int64_t x) {return x / 9223372036854775808.f;}
  36. /** Float to integer */
  37. template <>
  38. inline int8_t convert(float x) {return std::min(std::llround(x * 128.f), 127LL);}
  39. template <>
  40. inline int16_t convert(float x) {return std::min(std::llround(x * 32768.f), 32767LL);}
  41. template <>
  42. inline Int24 convert(float x) {return std::min(std::llround(x * 8388608.f), 8388607LL);}
  43. template <>
  44. inline int32_t convert(float x) {return std::min(std::llround(x * 2147483648.f), 2147483647LL);}
  45. template <>
  46. inline int64_t convert(float x) {return std::min(std::llround(x * 9223372036854775808.f), 9223372036854775807LL);}
  47. /** Buffer conversion */
  48. template <typename To, typename From>
  49. void convert(const From* in, To* out, size_t len) {
  50. for (size_t i = 0; i < len; i++) {
  51. out[i] = convert<To, From>(in[i]);
  52. }
  53. }
  54. } // namespace dsp
  55. } // namespace rack