Vital
Loading...
Searching...
No Matches
memory.h
Go to the documentation of this file.
1
10#pragma once
11
12#include "common.h"
13
14#include <algorithm>
15#include <cmath>
16#include <memory>
17
18#include "poly_utils.h"
19
20namespace vital {
21
32 template<size_t kChannels>
34 public:
35 static constexpr mono_float kMinPeriod = 2.0f;
36 static constexpr int kExtraInterpolationValues = 3;
37
42 MemoryTemplate(int size) : offset_(0) {
44 bitmask_ = size_ - 1;
45 for (int i = 0; i < static_cast<int>(kChannels); ++i) {
46 memories_[i] = std::make_unique<mono_float[]>(2 * size_);
47 buffers_[i] = memories_[i].get();
48 }
49 }
50
56 for (int i = 0; i < static_cast<int>(kChannels); ++i) {
57 memories_[i] = std::make_unique<mono_float[]>(2 * other.size_);
58 buffers_[i] = memories_[i].get();
59 }
60
61 size_ = other.size_;
62 bitmask_ = other.bitmask_;
63 offset_ = other.offset_;
64 }
65
69 virtual ~MemoryTemplate() { }
70
75 void push(poly_float sample) {
76 offset_ = (offset_ + 1) & bitmask_;
77 for (int i = 0; i < static_cast<int>(kChannels); ++i) {
78 mono_float val = sample[i];
79 buffers_[i][offset_] = val;
80 buffers_[i][offset_ + size_] = val;
81 }
82
84 }
85
91 void clearMemory(int num, poly_mask clear_mask) {
92 int start = (offset_ - (num + kExtraInterpolationValues)) & bitmask_;
94
95 for (int p = 0; p < static_cast<int>(kChannels); ++p) {
96 if (clear_mask[p]) {
97 mono_float* buffer = buffers_[p];
98 for (int i = start; i != end; i = (i + 1) & bitmask_)
99 buffer[i] = 0.0f;
100 buffer[end] = 0.0f;
101
102 for (int i = 0; i < kExtraInterpolationValues; ++i)
103 buffer[size_ + i] = 0.0f;
104 }
105 }
106 }
107
111 void clearAll() {
112 for (int c = 0; c < static_cast<int>(kChannels); ++c)
113 memset(buffers_[c], 0, 2 * size_ * sizeof(mono_float));
114 }
115
123 void readSamples(mono_float* output, int num_samples, int offset, int channel) const {
124 mono_float* buffer = buffers_[channel];
125 int bitmask = bitmask_;
126 int start_index = (offset_ - num_samples - offset) & bitmask;
127 for (int i = 0; i < num_samples; ++i)
128 output[i] = buffer[(i + start_index) & bitmask];
129 }
130
135 unsigned int getOffset() const { return offset_; }
136
141 void setOffset(int offset) { offset_ = offset; }
142
147 int getSize() const {
148 return size_;
149 }
150
155 int getMaxPeriod() const {
157 }
158
159 protected:
160 std::unique_ptr<mono_float[]> memories_[kChannels];
161 mono_float* buffers_[kChannels];
162 unsigned int size_;
163 unsigned int bitmask_;
164 unsigned int offset_;
165 };
166
174 class Memory : public MemoryTemplate<poly_float::kSize> {
175 public:
180 Memory(int size) : MemoryTemplate(size) { }
181
186 Memory(Memory& other) : MemoryTemplate(other) { }
187
197
198 poly_int past_index = utils::toInt(past);
199 poly_float t = utils::toFloat(past_index) - past + 1.0f;
200 matrix interpolation_matrix = utils::getCatmullInterpolationMatrix(t);
201
202 poly_int indices = (poly_int(offset_) - past_index - 2) & poly_int(bitmask_);
203 matrix value_matrix = utils::getValueMatrix(buffers_, indices);
204 value_matrix.transpose();
205 return interpolation_matrix.multiplyAndSumRows(value_matrix);
206 }
207 };
208
216 class StereoMemory : public MemoryTemplate<2> {
217 public:
222 StereoMemory(int size) : MemoryTemplate(size) { }
223
229
236 VITAL_ASSERT(poly_float::lessThan(past, 2.0f).anyMask() == 0);
237 VITAL_ASSERT(poly_float::greaterThan(past, getMaxPeriod()).anyMask() == 0);
238
239 poly_int past_index = utils::toInt(past);
240 poly_float t = utils::toFloat(past_index) - past + 1.0f;
241 matrix interpolation_matrix = utils::getCatmullInterpolationMatrix(t);
242
243 poly_int indices = (poly_int(offset_) - past_index - 2) & poly_int(bitmask_);
244 // Construct a value matrix for stereo (2 channels), zero-filling other rows if needed.
245 matrix value_matrix(utils::toPolyFloatFromUnaligned(buffers_[0] + indices[0]),
246 utils::toPolyFloatFromUnaligned(buffers_[1] + indices[1]), 0.0f, 0.0f);
247 value_matrix.transpose();
248 return interpolation_matrix.multiplyAndSumRows(value_matrix);
249 }
250 };
251
252} // namespace vital
A specialized MemoryTemplate for poly_float::kSize channels.
Definition memory.h:174
force_inline poly_float get(poly_float past) const
Retrieves a poly_float of samples from the memory using cubic interpolation.
Definition memory.h:194
Memory(int size)
Constructs a polyphonic memory with the given size.
Definition memory.h:180
Memory(Memory &other)
Copy constructor.
Definition memory.h:186
A template for a memory buffer that stores time-domain samples for one or more channels.
Definition memory.h:33
unsigned int getOffset() const
Gets the current offset (write position) in the buffer.
Definition memory.h:135
static constexpr int kExtraInterpolationValues
Extra values to support cubic interpolation.
Definition memory.h:36
unsigned int bitmask_
Bitmask for efficient modulo operations.
Definition memory.h:163
unsigned int size_
The size of the memory buffer.
Definition memory.h:162
void push(poly_float sample)
Pushes a poly_float of samples (one sample per channel) into the memory.
Definition memory.h:75
mono_float * buffers_[kChannels]
Raw pointers to each channel buffer.
Definition memory.h:161
void clearMemory(int num, poly_mask clear_mask)
Clears a specified number of samples in the memory for channels indicated by a mask.
Definition memory.h:91
void readSamples(mono_float *output, int num_samples, int offset, int channel) const
Reads samples from the memory into an output buffer.
Definition memory.h:123
int getMaxPeriod() const
Gets the maximum allowed period for reading samples.
Definition memory.h:155
void setOffset(int offset)
Sets the current offset (write position) in the buffer.
Definition memory.h:141
MemoryTemplate(int size)
Constructs the memory with a given size (rounded up to a power of two).
Definition memory.h:42
unsigned int offset_
Current write offset in the buffer.
Definition memory.h:164
std::unique_ptr< mono_float[]> memories_[kChannels]
Unique pointers to each channel's buffer.
Definition memory.h:160
virtual ~MemoryTemplate()
Destructor.
Definition memory.h:69
int getSize() const
Gets the size of the memory buffer.
Definition memory.h:147
static constexpr mono_float kMinPeriod
Minimum allowed period of time delay.
Definition memory.h:35
MemoryTemplate(const MemoryTemplate &other)
Copy constructor.
Definition memory.h:55
void clearAll()
Clears all samples in the memory for all channels.
Definition memory.h:111
A specialized MemoryTemplate for two-channel (stereo) audio.
Definition memory.h:216
force_inline poly_float get(poly_float past) const
Retrieves a poly_float of samples from the stereo memory using cubic interpolation.
Definition memory.h:235
StereoMemory(StereoMemory &other)
Copy constructor.
Definition memory.h:228
StereoMemory(int size)
Constructs a stereo memory with the given size.
Definition memory.h:222
#define VITAL_ASSERT(x)
Definition common.h:11
#define force_inline
Definition common.h:23
force_inline bool isFinite(poly_float value)
Checks if all lanes in a poly_float are finite.
Definition poly_utils.h:610
force_inline poly_float toFloat(poly_int integers)
Casts a poly_int to poly_float lane-by-lane.
Definition poly_utils.h:733
force_inline int nextPowerOfTwo(mono_float value)
Finds the next power of two greater than or equal to a float value.
Definition utils.h:370
force_inline poly_float toPolyFloatFromUnaligned(const mono_float *unaligned)
Loads a poly_float from an unaligned float pointer.
Definition poly_utils.h:249
force_inline matrix getCatmullInterpolationMatrix(poly_float t)
Creates a Catmull-Rom interpolation matrix from a poly_float t.
Definition poly_utils.h:227
force_inline matrix getValueMatrix(const mono_float *buffer, poly_int indices)
Creates a matrix of 4 poly_float lanes from a single buffer at varying indices.
Definition poly_utils.h:262
force_inline poly_int toInt(poly_float floats)
Casts a poly_float to poly_int by truncation.
Definition poly_utils.h:748
Contains classes and functions used within the Vital synthesizer framework.
float mono_float
Definition common.h:33
A structure representing a 4x1 matrix of poly_float rows.
Definition matrix.h:19
force_inline poly_float multiplyAndSumRows(const matrix &other)
Multiplies and sums corresponding rows of this matrix with another matrix.
Definition matrix.h:93
force_inline void transpose()
Transposes the matrix in-place.
Definition matrix.h:44
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600
static force_inline poly_mask vector_call lessThan(poly_float one, poly_float two)
Definition poly_values.h:1105
static force_inline mask_simd_type vector_call greaterThan(simd_type one, simd_type two)
Compares two SIMD float registers, element-wise, for greater than.
Definition poly_values.h:971
Represents a vector of integer values using SIMD instructions.
Definition poly_values.h:56