Krotos Modules 3
Loading...
Searching...
No Matches
Utilities.h
Go to the documentation of this file.
1// ==================================================================================
2// Copyright (c) 2017 HiFi-LoFi
3//
4// Permission is hereby granted, free of charge, to any person obtaining a copy
5// of this software and associated documentation files (the "Software"), to deal
6// in the Software without restriction, including without limitation the rights
7// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8// copies of the Software, and to permit persons to whom the Software is furnished
9// to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20// ==================================================================================
21
22#ifndef _FFTCONVOLVER_UTILITIES_H
23#define _FFTCONVOLVER_UTILITIES_H
24
25#include <algorithm>
26#include <cassert>
27#include <cstddef>
28#include <cstring>
29#include <new>
30
31namespace fftconvolver
32{
33
34#if defined(__SSE__) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
35#if !defined(FFTCONVOLVER_USE_SSE) && !defined(FFTCONVOLVER_DONT_USE_SSE)
36#define FFTCONVOLVER_USE_SSE
37#endif
38#endif
39
40#if defined(FFTCONVOLVER_USE_SSE)
41#include <xmmintrin.h>
42#endif
43
44#if defined(__GNUC__)
45#define FFTCONVOLVER_RESTRICT __restrict__
46#else
47#define FFTCONVOLVER_RESTRICT
48#endif
49
54 bool SSEEnabled();
55
60 template <typename T> class Buffer
61 {
62 public:
63 explicit Buffer(size_t initialSize = 0) : _data(nullptr), _size(0) { resize(initialSize); }
64
65 virtual ~Buffer() { clear(); }
66
67 void clear()
68 {
70 _data = nullptr;
71 _size = 0;
72 }
73
74 void resize(size_t size)
75 {
76 if (_size != size)
77 {
78 clear();
79
80 if (size > 0)
81 {
82 assert(!_data && _size == 0);
84 _size = size;
85 }
86 }
87 setZero();
88 }
89
90 size_t size() const { return _size; }
91
92 void setZero() { ::memset(_data, 0, _size * sizeof(T)); }
93
94 void copyFrom(const Buffer<T>& other)
95 {
96 assert(_size == other._size);
97 if (this != &other)
98 {
99 ::memcpy(_data, other._data, _size * sizeof(T));
100 }
101 }
102
103 T& operator[](size_t index)
104 {
105 assert(_data && index < _size);
106 return _data[index];
107 }
108
109 const T& operator[](size_t index) const
110 {
111 assert(_data && index < _size);
112 return _data[index];
113 }
114
115 operator bool() const { return (_data != 0 && _size > 0); }
116
117 T* data() { return _data; }
118
119 const T* data() const { return _data; }
120
121 static void Swap(Buffer<T>& a, Buffer<T>& b)
122 {
123 std::swap(a._data, b._data);
124 std::swap(a._size, b._size);
125 }
126
127 private:
128 T* allocate(size_t size)
129 {
130#if defined(FFTCONVOLVER_USE_SSE)
131 return static_cast<T*>(_mm_malloc(size * sizeof(T), 16));
132#else
133 return new T[size];
134#endif
135 }
136
137 void deallocate(T* ptr)
138 {
139#if defined(FFTCONVOLVER_USE_SSE)
140 _mm_free(ptr);
141#else
142 delete[] ptr;
143#endif
144 }
145
147 size_t _size;
148
149 // Prevent uncontrolled usage
150 Buffer(const Buffer&);
152 };
153
157 typedef float Sample;
158
163
173 {
174 public:
175 explicit SplitComplex(size_t initialSize = 0) : _size(0), _re(), _im() { resize(initialSize); }
176
178
179 void clear()
180 {
181 _re.clear();
182 _im.clear();
183 _size = 0;
184 }
185
186 void resize(size_t newSize)
187 {
188 _re.resize(newSize);
189 _im.resize(newSize);
190 _size = newSize;
191 }
192
193 void setZero()
194 {
195 _re.setZero();
196 _im.setZero();
197 }
198
199 void copyFrom(const SplitComplex& other)
200 {
201 _re.copyFrom(other._re);
202 _im.copyFrom(other._im);
203 }
204
205 Sample* re() { return _re.data(); }
206
207 const Sample* re() const { return _re.data(); }
208
209 Sample* im() { return _im.data(); }
210
211 const Sample* im() const { return _im.data(); }
212
213 size_t size() const { return _size; }
214
215 private:
216 size_t _size;
219
220 // Prevent uncontrolled usage
223 };
224
230 template <typename T> T NextPowerOf2(const T& val)
231 {
232 T nextPowerOf2 = 1;
233 while (nextPowerOf2 < val)
234 {
235 nextPowerOf2 *= 2;
236 }
237 return nextPowerOf2;
238 }
239
248 const Sample* FFTCONVOLVER_RESTRICT b, size_t len);
249
256 template <typename T> void CopyAndPad(Buffer<T>& dest, const T* src, size_t srcSize)
257 {
258 assert(dest.size() >= srcSize);
259 ::memcpy(dest.data(), src, srcSize * sizeof(T));
260 ::memset(dest.data() + srcSize, 0, (dest.size() - srcSize) * sizeof(T));
261 }
262
269 void ComplexMultiplyAccumulate(SplitComplex& result, const SplitComplex& a, const SplitComplex& b);
270
283 const size_t len);
284
285} // End of namespace fftconvolver
286
287#endif // Header guard
Simple buffer implementation (uses 16-byte alignment if SSE optimization is enabled)
Definition Utilities.h:61
T * data()
Definition Utilities.h:117
T * _data
Definition Utilities.h:146
void setZero()
Definition Utilities.h:92
void copyFrom(const Buffer< T > &other)
Definition Utilities.h:94
size_t _size
Definition Utilities.h:147
void resize(size_t size)
Definition Utilities.h:74
const T & operator[](size_t index) const
Definition Utilities.h:109
Buffer(size_t initialSize=0)
Definition Utilities.h:63
void deallocate(T *ptr)
Definition Utilities.h:137
T & operator[](size_t index)
Definition Utilities.h:103
Buffer(const Buffer &)
T * allocate(size_t size)
Definition Utilities.h:128
virtual ~Buffer()
Definition Utilities.h:65
size_t size() const
Definition Utilities.h:90
const T * data() const
Definition Utilities.h:119
static void Swap(Buffer< T > &a, Buffer< T > &b)
Definition Utilities.h:121
Buffer & operator=(const Buffer &)
void clear()
Definition Utilities.h:67
Buffer for split-complex representation of FFT results.
Definition Utilities.h:173
SplitComplex(size_t initialSize=0)
Definition Utilities.h:175
void setZero()
Definition Utilities.h:193
size_t size() const
Definition Utilities.h:213
const Sample * im() const
Definition Utilities.h:211
Sample * im()
Definition Utilities.h:209
SampleBuffer _re
Definition Utilities.h:217
void clear()
Definition Utilities.h:179
void copyFrom(const SplitComplex &other)
Definition Utilities.h:199
size_t _size
Definition Utilities.h:216
void resize(size_t newSize)
Definition Utilities.h:186
SampleBuffer _im
Definition Utilities.h:218
const Sample * re() const
Definition Utilities.h:207
SplitComplex(const SplitComplex &)
Sample * re()
Definition Utilities.h:205
~SplitComplex()
Definition Utilities.h:177
SplitComplex & operator=(const SplitComplex &)
Definition FFTConvolver.cpp:29
bool SSEEnabled()
Returns whether SSE optimization for the convolver is enabled.
Definition Utilities.cpp:27
Buffer< Sample > SampleBuffer
Buffer for samples.
Definition Utilities.h:162
float Sample
Type of one sample.
Definition Utilities.h:157
T NextPowerOf2(const T &val)
Returns the next power of 2 of a given number.
Definition Utilities.h:230
void ComplexMultiplyAccumulate(SplitComplex &result, const SplitComplex &a, const SplitComplex &b)
Adds the complex product of two split-complex buffers to a result buffer.
Definition Utilities.cpp:53
void CopyAndPad(Buffer< T > &dest, const T *src, size_t srcSize)
Copies a source array into a destination buffer and pads the destination buffer with zeros.
Definition Utilities.h:256
void Sum(Sample *FFTCONVOLVER_RESTRICT result, const Sample *FFTCONVOLVER_RESTRICT a, const Sample *FFTCONVOLVER_RESTRICT b, size_t len)
Sums two given sample arrays.
Definition Utilities.cpp:36
#define FFTCONVOLVER_RESTRICT
Definition Utilities.h:47