JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_SIMDRegister_Impl.h
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28namespace dsp
29{
30
31
32//==============================================================================
33template <typename Type>
35{
36 ElementAccess (const ElementAccess&) = default;
37 operator Type() const { return simd.get (idx); }
38 ElementAccess& operator= (Type scalar) noexcept { simd.set (idx, scalar); return *this; }
39 ElementAccess& operator= (const ElementAccess& o) noexcept { return operator= ((Type) o); }
40
41private:
42 friend struct SIMDRegister;
43 ElementAccess (SIMDRegister& owner, size_t index) noexcept : simd (owner), idx (index) {}
44 SIMDRegister& simd;
45 size_t idx;
46};
47
48#ifndef DOXYGEN
49//==============================================================================
50/* This class is used internally by SIMDRegister to abstract away differences
51 in operations which are different for complex and pure floating point types. */
52
53// the pure floating-point version
54template <typename Scalar>
55struct CmplxSIMDOps
56{
57 using vSIMDType = typename SIMDNativeOps<Scalar>::vSIMDType;
58
59 static vSIMDType JUCE_VECTOR_CALLTYPE load (const Scalar* a) noexcept
60 {
61 return SIMDNativeOps<Scalar>::load (a);
62 }
63
64 static void JUCE_VECTOR_CALLTYPE store (vSIMDType value, Scalar* dest) noexcept
65 {
66 SIMDNativeOps<Scalar>::store (value, dest);
67 }
68
69 static vSIMDType JUCE_VECTOR_CALLTYPE expand (Scalar s) noexcept
70 {
71 return SIMDNativeOps<Scalar>::expand (s);
72 }
73
74 static Scalar JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept
75 {
76 return SIMDNativeOps<Scalar>::get (v, i);
77 }
78
79 static vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, Scalar s) noexcept
80 {
81 return SIMDNativeOps<Scalar>::set (v, i, s);
82 }
83
84 static Scalar JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept
85 {
86 return SIMDNativeOps<Scalar>::sum (a);
87 }
88
89 static vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
90 {
91 return SIMDNativeOps<Scalar>::mul (a, b);
92 }
93
94 static vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept
95 {
96 return SIMDNativeOps<Scalar>::multiplyAdd (a, b, c);
97 }
98};
99
100// The pure complex version
101template <typename Scalar>
102struct CmplxSIMDOps<std::complex<Scalar>>
103{
104 using vSIMDType = typename SIMDNativeOps<Scalar>::vSIMDType;
105
106 static vSIMDType JUCE_VECTOR_CALLTYPE load (const std::complex<Scalar>* a) noexcept
107 {
108 return SIMDNativeOps<Scalar>::load (reinterpret_cast<const Scalar*> (a));
109 }
110
111 static void JUCE_VECTOR_CALLTYPE store (vSIMDType value, std::complex<Scalar>* dest) noexcept
112 {
113 SIMDNativeOps<Scalar>::store (value, reinterpret_cast<Scalar*> (dest));
114 }
115
116 static vSIMDType JUCE_VECTOR_CALLTYPE expand (std::complex<Scalar> s) noexcept
117 {
118 const int n = sizeof (vSIMDType) / sizeof (Scalar);
119
120 union
121 {
122 vSIMDType v;
123 Scalar floats[(size_t) n];
124 } u;
125
126 for (int i = 0; i < n; ++i)
127 u.floats[i] = (i & 1) == 0 ? s.real() : s.imag();
128
129 return u.v;
130 }
131
132 static std::complex<Scalar> JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept
133 {
134 auto j = i << 1;
135 return std::complex<Scalar> (SIMDNativeOps<Scalar>::get (v, j), SIMDNativeOps<Scalar>::get (v, j + 1));
136 }
137
138 static vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, std::complex<Scalar> s) noexcept
139 {
140 auto j = i << 1;
141 return SIMDNativeOps<Scalar>::set (SIMDNativeOps<Scalar>::set (v, j, s.real()), j + 1, s.imag());
142 }
143
144 static std::complex<Scalar> JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept
145 {
146 vSIMDType result = SIMDNativeOps<Scalar>::oddevensum (a);
147 auto* ptr = reinterpret_cast<const Scalar*> (&result);
148 return std::complex<Scalar> (ptr[0], ptr[1]);
149 }
150
151 static vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
152 {
153 return SIMDNativeOps<Scalar>::cmplxmul (a, b);
154 }
155
156 static vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept
157 {
158 return SIMDNativeOps<Scalar>::add (a, SIMDNativeOps<Scalar>::cmplxmul (b, c));
159 }
160};
161#endif
162
163//==============================================================================
164 namespace util
165 {
166 template <typename Type>
167 inline void snapToZero (SIMDRegister<Type>&) noexcept {}
168 }
169
170} // namespace dsp
171
172// Extend some common used global functions to SIMDRegister types
173template <typename Type>
174inline dsp::SIMDRegister<Type> JUCE_VECTOR_CALLTYPE jmin (dsp::SIMDRegister<Type> a, dsp::SIMDRegister<Type> b) { return dsp::SIMDRegister<Type>::min (a, b); }
175template <typename Type>
176inline dsp::SIMDRegister<Type> JUCE_VECTOR_CALLTYPE jmax (dsp::SIMDRegister<Type> a, dsp::SIMDRegister<Type> b) { return dsp::SIMDRegister<Type>::max (a, b); }
177
178} // namespace juce
auto & get(ProcessorChain< Processors... > &chain) noexcept
Non-member equivalent of ProcessorChain::get which avoids awkward member template syntax.
JUCE Namespace.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
A wrapper around the platform's native SIMD register type.
typename NativeOps::vSIMDType vSIMDType
The native type (used internally).
SIMDRegister &JUCE_VECTOR_CALLTYPE operator=(ElementType s) noexcept
Broadcasts the scalar to all elements of the receiver.
static SIMDRegister JUCE_VECTOR_CALLTYPE max(SIMDRegister a, SIMDRegister b) noexcept
Returns a new vector where each element is the maximum of the corresponding element of a and b.
static SIMDRegister JUCE_VECTOR_CALLTYPE min(SIMDRegister a, SIMDRegister b) noexcept
Returns a new vector where each element is the minimum of the corresponding element of a and b.
void JUCE_VECTOR_CALLTYPE set(size_t idx, ElementType v) noexcept
Sets the idx-th element of the receiver.
typedef size_t