Audio plugin host https://kx.studio/carla
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.

179 lines
5.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. namespace dsp
  21. {
  22. //==============================================================================
  23. template <typename Type>
  24. struct SIMDRegister<Type>::ElementAccess
  25. {
  26. ElementAccess (const ElementAccess&) = default;
  27. operator Type() const { return simd.get (idx); }
  28. ElementAccess& operator= (Type scalar) noexcept { simd.set (idx, scalar); return *this; }
  29. ElementAccess& operator= (const ElementAccess& o) noexcept { return operator= ((Type) o); }
  30. private:
  31. friend struct SIMDRegister;
  32. ElementAccess (SIMDRegister& owner, size_t index) noexcept : simd (owner), idx (index) {}
  33. SIMDRegister& simd;
  34. size_t idx;
  35. };
  36. #ifndef DOXYGEN
  37. //==============================================================================
  38. /* This class is used internally by SIMDRegister to abstract away differences
  39. in operations which are different for complex and pure floating point types. */
  40. // the pure floating-point version
  41. template <typename Scalar>
  42. struct CmplxSIMDOps
  43. {
  44. using vSIMDType = typename SIMDNativeOps<Scalar>::vSIMDType;
  45. static vSIMDType JUCE_VECTOR_CALLTYPE load (const Scalar* a) noexcept
  46. {
  47. return SIMDNativeOps<Scalar>::load (a);
  48. }
  49. static void JUCE_VECTOR_CALLTYPE store (vSIMDType value, Scalar* dest) noexcept
  50. {
  51. SIMDNativeOps<Scalar>::store (value, dest);
  52. }
  53. static vSIMDType JUCE_VECTOR_CALLTYPE expand (Scalar s) noexcept
  54. {
  55. return SIMDNativeOps<Scalar>::expand (s);
  56. }
  57. static Scalar JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept
  58. {
  59. return SIMDNativeOps<Scalar>::get (v, i);
  60. }
  61. static vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, Scalar s) noexcept
  62. {
  63. return SIMDNativeOps<Scalar>::set (v, i, s);
  64. }
  65. static Scalar JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept
  66. {
  67. return SIMDNativeOps<Scalar>::sum (a);
  68. }
  69. static vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
  70. {
  71. return SIMDNativeOps<Scalar>::mul (a, b);
  72. }
  73. static vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept
  74. {
  75. return SIMDNativeOps<Scalar>::multiplyAdd (a, b, c);
  76. }
  77. };
  78. // The pure complex version
  79. template <typename Scalar>
  80. struct CmplxSIMDOps<std::complex<Scalar>>
  81. {
  82. using vSIMDType = typename SIMDNativeOps<Scalar>::vSIMDType;
  83. static vSIMDType JUCE_VECTOR_CALLTYPE load (const std::complex<Scalar>* a) noexcept
  84. {
  85. return SIMDNativeOps<Scalar>::load (reinterpret_cast<const Scalar*> (a));
  86. }
  87. static void JUCE_VECTOR_CALLTYPE store (vSIMDType value, std::complex<Scalar>* dest) noexcept
  88. {
  89. SIMDNativeOps<Scalar>::store (value, reinterpret_cast<Scalar*> (dest));
  90. }
  91. static vSIMDType JUCE_VECTOR_CALLTYPE expand (std::complex<Scalar> s) noexcept
  92. {
  93. const int n = sizeof (vSIMDType) / sizeof (Scalar);
  94. union
  95. {
  96. vSIMDType v;
  97. Scalar floats[(size_t) n];
  98. } u;
  99. for (int i = 0; i < n; ++i)
  100. u.floats[i] = (i & 1) == 0 ? s.real() : s.imag();
  101. return u.v;
  102. }
  103. static std::complex<Scalar> JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept
  104. {
  105. auto j = i << 1;
  106. return std::complex<Scalar> (SIMDNativeOps<Scalar>::get (v, j), SIMDNativeOps<Scalar>::get (v, j + 1));
  107. }
  108. static vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, std::complex<Scalar> s) noexcept
  109. {
  110. auto j = i << 1;
  111. return SIMDNativeOps<Scalar>::set (SIMDNativeOps<Scalar>::set (v, j, s.real()), j + 1, s.imag());
  112. }
  113. static std::complex<Scalar> JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept
  114. {
  115. vSIMDType result = SIMDNativeOps<Scalar>::oddevensum (a);
  116. auto* ptr = reinterpret_cast<const Scalar*> (&result);
  117. return std::complex<Scalar> (ptr[0], ptr[1]);
  118. }
  119. static vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
  120. {
  121. return SIMDNativeOps<Scalar>::cmplxmul (a, b);
  122. }
  123. static vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept
  124. {
  125. return SIMDNativeOps<Scalar>::add (a, SIMDNativeOps<Scalar>::cmplxmul (b, c));
  126. }
  127. };
  128. #endif
  129. //==============================================================================
  130. namespace util
  131. {
  132. template <typename Type>
  133. inline void snapToZero (SIMDRegister<Type>&) noexcept {}
  134. }
  135. } // namespace dsp
  136. // Extend some common used global functions to SIMDRegister types
  137. template <typename Type>
  138. inline dsp::SIMDRegister<Type> JUCE_VECTOR_CALLTYPE jmin (dsp::SIMDRegister<Type> a, dsp::SIMDRegister<Type> b) { return dsp::SIMDRegister<Type>::min (a, b); }
  139. template <typename Type>
  140. inline dsp::SIMDRegister<Type> JUCE_VECTOR_CALLTYPE jmax (dsp::SIMDRegister<Type> a, dsp::SIMDRegister<Type> b) { return dsp::SIMDRegister<Type>::max (a, b); }
  141. } // namespace juce