Audacity 3.2.0
VectorOps.h
Go to the documentation of this file.
1//
2// This header is provided for convenience, to easily wrap vector operations around
3// their platform-specific optimised libraries (e.g. IPP, vDSP), if desired.
4// This can be done by adding #if defined(...) compile-time branches to each function
5// and calling the corresponding library function, e.g. ippsAdd_32f or vDSP_vadd
6// inside add().
7//
8
9#pragma once
10
11#include <stdlib.h>
12
13#include <complex>
14#include <cstdint>
15#include <cstring>
16
17#if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_X64) || \
18 (defined(_M_IX86_FP) && _M_IX86_FP >= 2))
19#define USE_SSE2_COMPLEX 1
20#endif
21
22#if USE_SSE2_COMPLEX
24#endif
25
26namespace staffpad {
27namespace vo {
28
29inline void* allocate(int32_t bytes)
30{
31 return ::malloc(bytes);
32}
33
34inline void free(void* ptr)
35{
36 return ::free(ptr);
37}
38
39template <class T>
40inline void copy(const T* src, T* dst, int32_t n)
41{
42 memcpy(dst, src, n * sizeof(T));
43}
44
45template <class T>
46inline void add(const T* src1, const T* src2, T* dst, int32_t n)
47{
48 for (int32_t i = 0; i < n; i++)
49 dst[i] = src1[i] + src2[i];
50}
51
52template <class T>
53inline void subtract(const T* src1, const T* src2, T* dst, int32_t n)
54{
55 for (int32_t i = 0; i < n; i++)
56 dst[i] = src2[i] - src1[i];
57}
58
59template <class T>
60inline void constantMultiply(const T* src, T constant, T* dst, int32_t n)
61{
62 for (int32_t i = 0; i < n; i++)
63 dst[i] = src[i] * constant;
64}
65
66template <class T>
67inline void constantMultiplyAndAdd(const T* src, T constant, T* dst, int32_t n)
68{
69 for (int32_t i = 0; i < n; i++)
70 dst[i] += src[i] * constant;
71}
72
73template <class T>
74inline void multiply(const T* src1, const T* src2, T* dst, int32_t n)
75{
76 for (int32_t i = 0; i < n; i++)
77 dst[i] = src1[i] * src2[i];
78}
79
80template <class T>
81inline void setToZero(T* dst, int32_t n)
82{
83 std::fill(dst, dst + n, 0.f);
84}
85
86template <class T>
87inline void findMaxElement(const T* src, int32_t n, int32_t& maxIndex, T& maxValue)
88{
89 maxIndex = 0;
90 maxValue = n > 0 ? src[0] : std::numeric_limits<T>::min();
91
92 for (int32_t i = 1; i < n; i++)
93 {
94 if (src[i] > maxValue)
95 {
96 maxValue = src[i];
97 maxIndex = i;
98 }
99 }
100}
101
102#if USE_SSE2_COMPLEX
103
104inline void calcPhases(const std::complex<float>* src, float* dst, int32_t n)
105{
107 src, dst, n,
108 [](const __m128 rp, const __m128 ip, __m128& out)
109 { out = simd_complex_conversions::atan2_ps(ip, rp); });
110}
111
112inline void calcNorms(const std::complex<float>* src, float* dst, int32_t n)
113{
115 src, dst, n,
116 [](const __m128 rp, const __m128 ip, __m128& out)
117 { out = simd_complex_conversions::norm(rp, ip); });
118}
119
120inline void rotate(
121 const float* oldPhase, const float* newPhase, std::complex<float>* dst,
122 int32_t n)
123{
125 oldPhase, newPhase, dst, n);
126}
127#else
128inline void calcPhases(const std::complex<float>* src, float* dst, int32_t n)
129{
130 for (int32_t i = 0; i < n; i++)
131 dst[i] = std::arg(src[i]);
132}
133
134inline void calcNorms(const std::complex<float>* src, float* dst, int32_t n)
135{
136 for (int32_t i = 0; i < n; i++)
137 dst[i] = std::norm(src[i]);
138}
139
140inline void rotate(const float* oldPhase, const float* newPhase, std::complex<float>* dst, int32_t n)
141{
142 for (int32_t i = 0; i < n; i++) {
143 const auto theta = oldPhase ? newPhase[i] - oldPhase[i] : newPhase[i];
144 dst[i] *= std::complex<float>(cosf(theta), sinf(theta));
145 }
146}
147#endif
148
149} // namespace vo
150} // namespace staffpad
int min(int a, int b)
__m128 atan2_ps(__m128 y, __m128 x)
__m128 norm(__m128 x, __m128 y)
void perform_parallel_simd_aligned(const std::complex< float > *input, float *output, int n, const fnc &f)
void rotate_parallel_simd_aligned(const float *oldPhase, const float *newPhase, std::complex< float > *output, int n)
void * allocate(int32_t bytes)
Definition: VectorOps.h:29
void subtract(const T *src1, const T *src2, T *dst, int32_t n)
Definition: VectorOps.h:53
void multiply(const T *src1, const T *src2, T *dst, int32_t n)
Definition: VectorOps.h:74
void calcPhases(const std::complex< float > *src, float *dst, int32_t n)
Definition: VectorOps.h:128
void rotate(const float *oldPhase, const float *newPhase, std::complex< float > *dst, int32_t n)
Definition: VectorOps.h:140
void setToZero(T *dst, int32_t n)
Definition: VectorOps.h:81
void findMaxElement(const T *src, int32_t n, int32_t &maxIndex, T &maxValue)
Definition: VectorOps.h:87
void add(const T *src1, const T *src2, T *dst, int32_t n)
Definition: VectorOps.h:46
void free(void *ptr)
Definition: VectorOps.h:34
void calcNorms(const std::complex< float > *src, float *dst, int32_t n)
Definition: VectorOps.h:134
void constantMultiplyAndAdd(const T *src, T constant, T *dst, int32_t n)
Definition: VectorOps.h:67
void copy(const T *src, T *dst, int32_t n)
Definition: VectorOps.h:40
void constantMultiply(const T *src, T constant, T *dst, int32_t n)
Definition: VectorOps.h:60