Vital
Loading...
Searching...
No Matches
synth_lfo.cpp
Go to the documentation of this file.
1#include "synth_lfo.h"
2
3#include "common.h"
4#include "line_generator.h"
5#include "synth_constants.h"
6#include "utils.h"
7
8#include <cmath>
9
10namespace vital {
11 SynthLfo::SynthLfo(LineGenerator* source) : Processor(kNumInputs, kNumOutputs), source_(source) {
12 was_control_rate_ = true;
13 sync_seconds_ = std::make_shared<double>();
14 *sync_seconds_ = 0;
15
17 }
18
26 int sync_type = input(kSyncType)->at(0)[0];
28 poly_mask release_mask = getReleaseMask();
29 held_mask_ = (held_mask_ | reset_mask) & ~release_mask;
31 trigger_sample_ = utils::maskLoad(trigger_sample_, trigger_offset, (reset_mask | release_mask));
32
39
40 poly_float trigger_delay = utils::toFloat(trigger_offset) * (1.0f / getSampleRate());
41 trigger_delay_ = utils::maskLoad(trigger_delay_, trigger_delay, reset_mask);
42
43 if (reset_mask.anyMask()) {
44 poly_float frequency = input(kFrequency)->at(0);
45
46 if (sync_type == kSync) {
47 // For sync mode, align offset with the external time reference.
51 }
52 else {
53 // For non-sync, simply reset offset to zero (or adjust by the triggered sample offset).
55
56 poly_float sample_offset = utils::toFloat(trigger_offset) & reset_mask;
57 poly_float offset_start = frequency * sample_offset * (1.0f / getSampleRate());
59 }
60 }
61 }
62
63 void SynthLfo::processControlRate(int num_samples) {
70 poly_float delay_time = input(kDelay)->at(0);
71
72 float tick_time = 1.0f / getSampleRate();
73 poly_float time_passed = tick_time * num_samples;
75 time_passed = utils::clamp(control_rate_state_.delay_time_passed - delay_time, 0.0f, time_passed);
76
77 poly_float stereo_phase = input(kStereoPhase)->at(0);
78 poly_float phase = input(kPhase)->at(0) + stereo_phase * poly_float(0.5f, -0.5f);
79 poly_float frequency = input(kFrequency)->at(0);
80 poly_float current_offset = control_rate_state_.offset;
81 control_rate_state_.offset += frequency * time_passed;
82
83 poly_float phased_offset;
84 int sync_type = input(kSyncType)->at(0)[0];
85 // Apply logic based on sync type
86 if (sync_type == kEnvelope) {
88 phased_offset = utils::min(current_offset + phase, 1.0f);
89 }
90 else if (sync_type == kSustainEnvelope) {
92 phased_offset = current_offset;
93 }
94 else if (sync_type == kTrigger || sync_type == kSync) {
96 phased_offset = utils::mod(current_offset + phase);
97 }
98 else if (sync_type == kLoopPoint) {
101 control_rate_state_.offset - 1.0f + phase, over);
102 phased_offset = utils::min(current_offset, 1.0f);
103 }
104 else if (sync_type == kLoopHold) {
107 control_rate_state_.offset - phase, over), 1.0f);
108 phased_offset = utils::maskLoad(current_offset, utils::min(current_offset, phase), held_mask_);
109 }
110
111 poly_float fade_time = input(kFade)->at(0);
112 poly_float fade_increase = time_passed / utils::max(utils::max(tick_time, time_passed), fade_time);
115 1.0f, poly_float::equal(fade_time, 0.0f));
116
117 poly_float value = getValueAtPhase(phased_offset);
118 poly_float result;
119 if (input(kSmoothMode)->at(0)[0]) {
120 // Smoothing the output value over time using exponential decay based on half-life.
121 poly_float half_life = input(kSmoothTime)->at(0) * kHalfLifeRatio;
122 poly_mask smooth_mask = poly_float::greaterThan(half_life, kMinHalfLife);
123 poly_float exponent = -time_passed / utils::max(half_life, kMinHalfLife);
124 poly_float ratio = futils::exp2(exponent);
125 ratio = ratio & smooth_mask;
128 }
129 else {
130 // If no smoothing, interpolate based on fade amplitude from the start phase.
131 poly_float start_value = getValueAtPhase(phase);
132 result = utils::interpolate(start_value, value, control_rate_state_.fade_amplitude);
133 }
134
135 result = utils::clamp(result, -1.0f, 1.0f);
136 output(kValue)->trigger_value = result;
137 if (isControlRate())
138 output(kValue)->buffer[0] = result;
139 output(kOscPhase)->buffer[0] = utils::encodePhaseAndVoice(phased_offset, input(kNoteCount)->at(0));
140 output(kOscFrequency)->buffer[0] = frequency;
141 }
142
143 /*
144 * The following audio-rate methods (processAudioRateEnvelope, processAudioRateSustainEnvelope, etc.)
145 * follow a similar pattern: they integrate the phase and offset over each sample,
146 * apply smoothing, fades, and delays, and write out a processed buffer of LFO values.
147 *
148 * They each handle a different sync mode, applying that mode's rules for
149 * looping, holding, or envelope stopping, and produce a continuous buffer of LFO samples.
150 */
152 poly_float current_offset, poly_float delta_offset) {
153 int lfo_resolution = source_->resolution();
154 poly_float resolution = lfo_resolution;
155 poly_int max_index = lfo_resolution - 1;
157 poly_float delta_phase = (audio_rate_state_.phase - current_phase) * (1.0f / num_samples);
158
159 poly_float fade_time = input(kFade)->at(0);
160 poly_float delay_time = input(kDelay)->at(0) + trigger_delay_;
162 poly_float current_amplitude = audio_rate_state_.fade_amplitude;
163 poly_float tick_time = 1.0f / getSampleRate();
164 poly_float fade_increase = tick_time / utils::max(tick_time, fade_time);
165
166 poly_float smooth_mult = 0.0f;
167 if (input(kSmoothMode)->at(0)[0]) {
168 poly_float half_life = input(kSmoothTime)->at(0) * kHalfLifeRatio;
169 poly_mask smooth_mask = poly_float::greaterThan(half_life, kMinHalfLife);
170 poly_float exponent = poly_float(-tick_time) / utils::max(half_life, kMinHalfLife);
171 smooth_mult = futils::exp2(exponent);
172 smooth_mult = smooth_mult & smooth_mask;
173 current_amplitude = 1.0f;
174 }
175
176 poly_float* dest = output(kValue)->buffer;
177 poly_float phased_offset = 0.0f;
179
180 for (int i = 0; i < num_samples; ++i) {
181 delay_time_passed += tick_time;
182 poly_mask past_delay_mask = poly_float::greaterThanOrEqual(delay_time_passed, delay_time);
183 current_amplitude = utils::clamp(current_amplitude + (fade_increase & past_delay_mask), 0.0f, 1.0f);
184 phased_offset = utils::min(current_offset + current_phase, 1.0f);
185 poly_float value = getValueAtPhase(lfo_buffer, resolution, max_index, phased_offset);
186 current_value = utils::interpolate(value, current_value, smooth_mult);
187 dest[i] = current_amplitude * current_value;
188
189 current_offset = utils::min(current_offset + (delta_offset & past_delay_mask), 1.0f);
190 current_phase += delta_phase;
191 }
192
193 audio_rate_state_.smooth_value = current_value;
194 audio_rate_state_.fade_amplitude = current_amplitude;
195 audio_rate_state_.delay_time_passed = delay_time_passed;
196 audio_rate_state_.offset = utils::min(current_offset, 1.0f);
197 return phased_offset;
198 }
199
201 poly_float current_offset, poly_float delta_offset) {
202 int lfo_resolution = source_->resolution();
203 poly_float resolution = lfo_resolution;
204 poly_int max_index = lfo_resolution - 1;
206 poly_float delta_phase = (audio_rate_state_.phase - current_phase) * (1.0f / num_samples);
207
208 poly_float fade_time = input(kFade)->at(0);
209 poly_float delay_time = input(kDelay)->at(0) + trigger_delay_;
211 poly_float current_amplitude = audio_rate_state_.fade_amplitude;
212 poly_float tick_time = 1.0f / getSampleRate();
213 poly_float fade_increase = tick_time / utils::max(tick_time, fade_time);
214
215 poly_float smooth_mult = 0.0f;
216 if (input(kSmoothMode)->at(0)[0]) {
217 poly_float half_life = input(kSmoothTime)->at(0) * kHalfLifeRatio;
218 poly_mask smooth_mask = poly_float::greaterThan(half_life, kMinHalfLife);
219 poly_float exponent = poly_float(-tick_time) / utils::max(half_life, kMinHalfLife);
220 smooth_mult = futils::exp2(exponent);
221 smooth_mult = smooth_mult & smooth_mask;
222 current_amplitude = 1.0f;
223 }
224
225 poly_float* dest = output(kValue)->buffer;
226
227 poly_mask current_hold_mask;
228 poly_mask held_mask = held_mask_;
229 poly_int trigger_sample = trigger_sample_;
231
232 for (int i = 0; i < num_samples; ++i) {
233 delay_time_passed += tick_time;
234 poly_mask past_delay_mask = poly_float::greaterThanOrEqual(delay_time_passed, delay_time);
235 current_amplitude = utils::clamp(current_amplitude + (fade_increase & past_delay_mask), 0.0f, 1.0f);
236
237 current_hold_mask = utils::maskLoad(current_hold_mask, held_mask, poly_int::equal(i, trigger_sample));
238 poly_float max = utils::maskLoad(1.0f, current_phase, current_hold_mask);
239 poly_float value = getValueAtPhase(lfo_buffer, resolution, max_index, current_offset);
240 current_value = utils::interpolate(value, current_value, smooth_mult);
241 dest[i] = current_amplitude * current_value;
242
243 current_offset = utils::min(current_offset + (delta_offset & past_delay_mask), max);
244 current_phase += delta_phase;
245 }
246
247 audio_rate_state_.smooth_value = current_value;
248 audio_rate_state_.fade_amplitude = current_amplitude;
249 audio_rate_state_.delay_time_passed = delay_time_passed;
250 poly_float last_max = utils::maskLoad(1.0f, current_phase, current_hold_mask);
251 audio_rate_state_.offset = utils::min(current_offset, last_max);
252 return current_offset;
253 }
254
256 poly_float current_offset, poly_float delta_offset) {
257 int lfo_resolution = source_->resolution();
258 poly_float resolution = lfo_resolution;
259 poly_int max_index = lfo_resolution - 1;
261 poly_float delta_phase = (audio_rate_state_.phase - current_phase) * (1.0f / num_samples);
262
263 poly_float fade_time = input(kFade)->at(0);
264 poly_float delay_time = input(kDelay)->at(0) + trigger_delay_;
266 poly_float current_amplitude = audio_rate_state_.fade_amplitude;
267 poly_float tick_time = 1.0f / getSampleRate();
268 poly_float fade_increase = tick_time / utils::max(tick_time, fade_time);
269
270 poly_float smooth_mult = 0.0f;
271 if (input(kSmoothMode)->at(0)[0]) {
272 poly_float half_life = input(kSmoothTime)->at(0) * kHalfLifeRatio;
273 poly_mask smooth_mask = poly_float::greaterThan(half_life, kMinHalfLife);
274 poly_float exponent = poly_float(-tick_time) / utils::max(half_life, kMinHalfLife);
275 smooth_mult = futils::exp2(exponent);
276 smooth_mult = smooth_mult & smooth_mask;
277 current_amplitude = 1.0f;
278 }
279
280 poly_mask delaying_mask = poly_float::greaterThan(delay_time, delay_time_passed);
281 poly_float* dest = output(kValue)->buffer;
282 poly_float phased_offset = 0.0f;
284
285 for (int i = 0; i < num_samples; ++i) {
286 delay_time_passed += tick_time;
287 poly_mask past_delay_mask = poly_float::greaterThanOrEqual(delay_time_passed, delay_time);
288 current_amplitude = utils::clamp(current_amplitude + (fade_increase & past_delay_mask), 0.0f, 1.0f);
289
290 phased_offset = utils::mod(current_offset + current_phase);
291 poly_float value = getValueAtPhase(lfo_buffer, resolution, max_index, phased_offset);
292 current_value = utils::interpolate(value, current_value, smooth_mult);
293 dest[i] = current_amplitude * current_value;
294
295 current_offset = utils::mod(current_offset + (delta_offset & past_delay_mask));
296 current_phase += delta_phase;
297 }
298
299 audio_rate_state_.smooth_value = current_value;
300 audio_rate_state_.fade_amplitude = current_amplitude;
301 audio_rate_state_.delay_time_passed = delay_time_passed;
302 poly_float undelayed_offset = utils::mod(audio_rate_state_.offset + delta_offset * num_samples);
303 audio_rate_state_.offset = utils::maskLoad(undelayed_offset, current_offset, delaying_mask);
304 return phased_offset;
305 }
306
308 poly_float current_offset, poly_float delta_offset) {
309 int lfo_resolution = source_->resolution();
310 poly_float resolution = lfo_resolution;
311 poly_int max_index = lfo_resolution - 1;
313 poly_float delta_phase = (audio_rate_state_.phase - current_phase) * (1.0f / num_samples);
314
315 poly_float fade_time = input(kFade)->at(0);
316 poly_float delay_time = input(kDelay)->at(0) + trigger_delay_;
318 poly_float current_amplitude = audio_rate_state_.fade_amplitude;
319 poly_float tick_time = 1.0f / getSampleRate();
320 poly_float fade_increase = tick_time / utils::max(tick_time, fade_time);
321
322 poly_float smooth_mult = 0.0f;
323 if (input(kSmoothMode)->at(0)[0]) {
324 poly_float half_life = input(kSmoothTime)->at(0) * kHalfLifeRatio;
325 poly_mask smooth_mask = poly_float::greaterThan(half_life, kMinHalfLife);
326 poly_float exponent = poly_float(-tick_time) / utils::max(half_life, kMinHalfLife);
327 smooth_mult = futils::exp2(exponent);
328 smooth_mult = smooth_mult & smooth_mask;
329 current_amplitude = 1.0f;
330 }
331
332 poly_float* dest = output(kValue)->buffer;
334
335 for (int i = 0; i < num_samples; ++i) {
336 delay_time_passed += tick_time;
337 poly_mask past_delay_mask = poly_float::greaterThanOrEqual(delay_time_passed, delay_time);
338 current_amplitude = utils::clamp(current_amplitude + (fade_increase & past_delay_mask), 0.0f, 1.0f);
339
340 current_offset += delta_offset & past_delay_mask;
341 poly_mask over = poly_float::greaterThanOrEqual(current_offset, 1.0f);
342 current_offset = utils::min(utils::maskLoad(current_offset, current_offset - 1.0f + current_phase, over), 1.0f);
343 poly_float value = getValueAtPhase(lfo_buffer, resolution, max_index, current_offset);
344 current_value = utils::interpolate(value, current_value, smooth_mult);
345 dest[i] = current_amplitude * current_value;
346 current_phase += delta_phase;
347 }
348
349 audio_rate_state_.smooth_value = current_value;
350 audio_rate_state_.fade_amplitude = current_amplitude;
351 audio_rate_state_.delay_time_passed = delay_time_passed;
352 audio_rate_state_.offset = current_offset;
353 return current_offset;
354 }
355
357 poly_float current_offset, poly_float delta_offset) {
358 int lfo_resolution = source_->resolution();
359 poly_float resolution = lfo_resolution;
360 poly_int max_index = lfo_resolution - 1;
362 poly_float delta_phase = (audio_rate_state_.phase - current_phase) * (1.0f / num_samples);
363
364 poly_float fade_time = input(kFade)->at(0);
365 poly_float delay_time = input(kDelay)->at(0) + trigger_delay_;
367 poly_float current_amplitude = audio_rate_state_.fade_amplitude;
368 poly_float tick_time = 1.0f / getSampleRate();
369 poly_float fade_increase = tick_time / utils::max(tick_time, fade_time);
370
371 poly_float smooth_mult = 0.0f;
372 if (input(kSmoothMode)->at(0)[0]) {
373 poly_float half_life = input(kSmoothTime)->at(0) * kHalfLifeRatio;
374 poly_mask smooth_mask = poly_float::greaterThan(half_life, kMinHalfLife);
375 poly_float exponent = poly_float(-tick_time) / utils::max(half_life, kMinHalfLife);
376 smooth_mult = futils::exp2(exponent);
377 smooth_mult = smooth_mult & smooth_mask;
378 current_amplitude = 1.0f;
379 }
380
381 poly_float* dest = output(kValue)->buffer;
382 poly_mask held_mask = held_mask_;
384
385 for (int i = 0; i < num_samples; ++i) {
386 delay_time_passed += tick_time;
387 poly_mask past_delay_mask = poly_float::greaterThanOrEqual(delay_time_passed, delay_time);
388 current_amplitude = utils::clamp(current_amplitude + (fade_increase & past_delay_mask), 0.0f, 1.0f);
389
390 current_offset += delta_offset & past_delay_mask;
391 poly_mask over = held_mask & poly_float::greaterThanOrEqual(current_offset, current_phase);
392 current_offset = utils::min(utils::maskLoad(current_offset, current_offset - current_phase, over), 1.0f);
393 poly_float value = getValueAtPhase(lfo_buffer, resolution, max_index, current_offset);
394 current_value = utils::interpolate(value, current_value, smooth_mult);
395 dest[i] = current_amplitude * current_value;
396 current_phase += delta_phase;
397 }
398
399 audio_rate_state_.smooth_value = current_value;
400 audio_rate_state_.fade_amplitude = current_amplitude;
401 audio_rate_state_.delay_time_passed = delay_time_passed;
402 audio_rate_state_.offset = current_offset;
403 return current_offset;
404 }
405
406 void SynthLfo::processAudioRate(int num_samples) {
407 poly_float fade_time = input(kFade)->at(0);
408 poly_float delay_time = input(kDelay)->at(0);
409
410 poly_float stereo_phase = input(kStereoPhase)->at(0);
411 poly_float current_phase = audio_rate_state_.phase;
412 audio_rate_state_.phase = input(kPhase)->at(0) + stereo_phase * poly_float(0.5f, -0.5f);
413
414 int sync_type = input(kSyncType)->at(0)[0];
415 if (sync_type == kSustainEnvelope)
416 current_phase = utils::maskLoad(current_phase, 0.0f, getResetMask(kNoteTrigger));
417 else
418 current_phase = utils::maskLoad(current_phase, audio_rate_state_.phase, getResetMask(kNoteTrigger));
419
420 poly_float frequency = input(kFrequency)->at(0);
421 float tick_time = 1.0f / getSampleRate();
422 poly_float delta_offset = frequency * tick_time;
423
424 poly_float output_phase = 0.0f;
426 if (sync_type == kEnvelope)
427 output_phase = processAudioRateEnvelope(num_samples, current_phase, offset, delta_offset);
428 else if (sync_type == kSustainEnvelope)
429 output_phase = processAudioRateSustainEnvelope(num_samples, current_phase, offset, delta_offset);
430 else if (sync_type == kTrigger || sync_type == kSync)
431 output_phase = processAudioRateLfo(num_samples, current_phase, offset, delta_offset);
432 else if (sync_type == kLoopPoint)
433 output_phase = processAudioRateLoopPoint(num_samples, current_phase, offset, delta_offset);
434 else if (sync_type == kLoopHold)
435 output_phase = processAudioRateLoopHold(num_samples, current_phase, offset, delta_offset);
436
438 output(kOscFrequency)->buffer[0] = frequency;
439 }
440
441 void SynthLfo::process(int num_samples) {
448 bool control_rate = isControlRate();
449 if (was_control_rate_ && !control_rate)
451 was_control_rate_ = control_rate;
452
454
455 if (!control_rate)
456 processAudioRate(num_samples);
457 processControlRate(num_samples);
458 }
459
460 void SynthLfo::correctToTime(double seconds) {
464 *sync_seconds_ = seconds;
465 }
466} // namespace vital
A class for generating and storing a line shape, defined by a series of points and associated powers.
Definition line_generator.h:20
force_inline int resolution() const
Gets the resolution of the line's internal buffer.
Definition line_generator.h:266
force_inline vital::mono_float * getCubicInterpolationBuffer() const
Gets a pointer to the buffer used for cubic interpolation.
Definition line_generator.h:298
Base class for all signal-processing units in Vital.
Definition processor.h:212
force_inline Input * input(unsigned int index=0) const
Retrieves the Input pointer at a given index.
Definition processor.h:587
force_inline int getSampleRate() const
Retrieves the current (effective) sample rate.
Definition processor.h:326
force_inline bool isControlRate() const
Checks if this Processor is running at control rate (buffer_size == 1).
Definition processor.h:342
force_inline poly_mask getResetMask(int input_index) const
Retrieves a mask indicating which voices triggered a note-on event. Compares the input's trigger_valu...
Definition processor.h:360
force_inline Output * output(unsigned int index=0) const
Retrieves the Output pointer at a given index.
Definition processor.h:616
force_inline poly_mask getReleaseMask()
Determines which voices are in the release state based on note triggers.
Definition synth_lfo.h:163
void processTrigger()
Handles trigger events (note on/off), resets, and updates masks for held states.
Definition synth_lfo.cpp:19
LfoState audio_rate_state_
State used during audio-rate processing.
Definition synth_lfo.h:254
poly_float processAudioRateSustainEnvelope(int num_samples, poly_float current_phase, poly_float current_offset, poly_float delta_offset)
Processes the LFO in "Sustain Envelope" mode at audio rate.
Definition synth_lfo.cpp:200
poly_float trigger_delay_
The delay (in seconds) to apply before the LFO starts after a trigger.
Definition synth_lfo.h:258
void process(int num_samples) override
Processes a block of samples, updating the LFO output.
Definition synth_lfo.cpp:441
void correctToTime(double seconds)
Updates the LFO to align with a given time in seconds, enabling synchronization with an external cloc...
Definition synth_lfo.cpp:460
void processAudioRate(int num_samples)
Processes the LFO at audio rate (per sample).
Definition synth_lfo.cpp:406
static constexpr float kMinHalfLife
Definition synth_lfo.h:118
@ kValue
Definition synth_lfo.h:56
@ kOscPhase
Definition synth_lfo.h:57
@ kOscFrequency
Definition synth_lfo.h:58
std::shared_ptr< double > sync_seconds_
Shared pointer to an external time reference for syncing.
Definition synth_lfo.h:262
poly_int trigger_sample_
The sample index at which the note was triggered.
Definition synth_lfo.h:257
poly_float processAudioRateLoopPoint(int num_samples, poly_float current_phase, poly_float current_offset, poly_float delta_offset)
Processes the LFO in "LoopPoint" mode at audio rate.
Definition synth_lfo.cpp:307
void processControlRate(int num_samples)
Processes the LFO at control rate (e.g., once per block) instead of every sample.
Definition synth_lfo.cpp:63
poly_mask held_mask_
A mask indicating which voices are currently held (for sustain envelope modes).
Definition synth_lfo.h:256
@ kEnvelope
Definition synth_lfo.h:75
@ kSustainEnvelope
Definition synth_lfo.h:76
@ kSync
Definition synth_lfo.h:74
@ kLoopPoint
Definition synth_lfo.h:77
@ kTrigger
Definition synth_lfo.h:73
@ kLoopHold
Definition synth_lfo.h:78
LineGenerator * source_
The LineGenerator providing the waveform data for the LFO.
Definition synth_lfo.h:260
force_inline poly_float getValueAtPhase(mono_float *buffer, poly_float resolution, poly_int max_index, poly_float phase)
Retrieves the LFO value at a given phase using a cubic interpolation on the line generator data.
Definition synth_lfo.h:129
LfoState control_rate_state_
State used during control-rate processing.
Definition synth_lfo.h:253
poly_float processAudioRateEnvelope(int num_samples, poly_float current_phase, poly_float current_offset, poly_float delta_offset)
Processes the LFO in "Envelope" sync mode at audio rate.
Definition synth_lfo.cpp:151
SynthLfo(LineGenerator *source)
Constructs a SynthLfo processor with a given LineGenerator source.
Definition synth_lfo.cpp:11
bool was_control_rate_
Tracks if the previous processing block was at control rate.
Definition synth_lfo.h:252
poly_float processAudioRateLfo(int num_samples, poly_float current_phase, poly_float current_offset, poly_float delta_offset)
Processes the LFO in regular LFO mode (Trigger or Sync) at audio rate.
Definition synth_lfo.cpp:255
poly_float processAudioRateLoopHold(int num_samples, poly_float current_phase, poly_float current_offset, poly_float delta_offset)
Processes the LFO in "LoopHold" mode at audio rate.
Definition synth_lfo.cpp:356
static constexpr float kHalfLifeRatio
Definition synth_lfo.h:117
@ kPhase
Definition synth_lfo.h:35
@ kFade
Definition synth_lfo.h:40
@ kSmoothMode
Definition synth_lfo.h:39
@ kSmoothTime
Definition synth_lfo.h:41
@ kDelay
Definition synth_lfo.h:43
@ kFrequency
Definition synth_lfo.h:34
@ kSyncType
Definition synth_lfo.h:38
@ kStereoPhase
Definition synth_lfo.h:42
@ kNoteCount
Definition synth_lfo.h:44
@ kNoteTrigger
Definition synth_lfo.h:37
#define force_inline
Definition common.h:23
force_inline poly_float exp2(poly_float exponent)
Approximates 2^exponent for poly_float values using a polynomial approximation.
Definition futils.h:45
force_inline poly_float mod(poly_float value)
Returns the fractional part of each lane by subtracting the floored value.
Definition poly_utils.h:814
force_inline poly_float clamp(poly_float value, mono_float min, mono_float max)
Clamps each lane of a vector to [min, max].
Definition poly_utils.h:306
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 poly_float encodePhaseAndVoice(poly_float phase, poly_float voice)
Encodes a phase [0..1) and a voice index into a single float, storing the voice in the integer portio...
Definition poly_utils.h:979
force_inline poly_float min(poly_float left, poly_float right)
Returns the minimum of two poly_floats lane-by-lane.
Definition poly_utils.h:334
force_inline poly_float getCycleOffsetFromSeconds(double seconds, poly_float frequency)
Computes a cycle offset given a time in seconds and a frequency.
Definition poly_utils.h:885
force_inline poly_float max(poly_float left, poly_float right)
Returns the maximum of two poly_floats lane-by-lane.
Definition poly_utils.h:327
force_inline poly_float maskLoad(poly_float zero_value, poly_float one_value, poly_mask reset_mask)
Selects between two values (zero_value or one_value) based on a mask in each lane.
Definition poly_utils.h:351
force_inline poly_float interpolate(poly_float from, poly_float to, mono_float t)
Performs a linear interpolation between two poly_floats using a scalar t in [0..1].
Definition poly_utils.h:182
Contains classes and functions used within the Vital synthesizer framework.
float mono_float
Definition common.h:33
force_inline poly_float at(int i) const
Returns the sample at index i from the source buffer.
Definition processor.h:141
const Output * source
The output from which this input reads samples.
Definition processor.h:134
poly_float * buffer
Pointer to the output buffer.
Definition processor.h:110
poly_int trigger_offset
Sample offset (per voice) for triggers.
Definition processor.h:117
poly_float trigger_value
Trigger values for voices.
Definition processor.h:116
poly_float offset
The current LFO offset (phase offset).
Definition synth_lfo.h:112
poly_float delay_time_passed
How much time has passed since the LFO was triggered or started its delay.
Definition synth_lfo.h:108
poly_float smooth_value
The stored value for applying smoothing between updates.
Definition synth_lfo.h:110
poly_float fade_amplitude
The current fade-in amplitude value.
Definition synth_lfo.h:109
poly_float phase
The current LFO phase.
Definition synth_lfo.h:113
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600
static force_inline mask_simd_type vector_call greaterThanOrEqual(simd_type one, simd_type two)
Compares two SIMD float registers, element-wise, for greater than or equal.
Definition poly_values.h:987
static force_inline mask_simd_type vector_call equal(simd_type one, simd_type two)
Compares two SIMD float registers for equality, element-wise.
Definition poly_values.h:954
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
static force_inline uint32_t vector_call anyMask(simd_type value)
Returns a bitmask that indicates which bytes/elements in the register are non-zero.
Definition poly_values.h:352
static force_inline simd_type vector_call equal(simd_type one, simd_type two)
Compares two SIMD integer registers for equality, element-wise.
Definition poly_values.h:291
Provides various utility functions, classes, and constants for audio, math, and general-purpose opera...