Vital
Loading...
Searching...
No Matches
portamento_slope.cpp
Go to the documentation of this file.
1
6#include "portamento_slope.h"
7#include "utils.h"
8#include "futils.h"
9
10namespace vital {
11
13 Processor(kNumInputs, 1, true),
14 position_(0.0f) { }
15
17 // If bypassed (no portamento), set position to 1.0 (fully at target)
18 position_ = 1.0f;
19 // Directly output target value as no portamento is occurring.
20 output()->buffer[0] = input(kTarget)->source->buffer[0];
21 }
22
23 void PortamentoSlope::process(int num_samples) {
24 bool force = input(kPortamentoForce)->at(0)[0];
25 poly_float run_seconds = input(kRunSeconds)->at(0);
26
27 // Determine if the portamento is active (run_seconds > minimum)
28 poly_mask active_mask = poly_float::greaterThan(run_seconds, kMinPortamentoTime);
29 if (active_mask.anyMask() == 0) {
30 // If not active, just bypass.
32 return;
33 }
34
35 // Check for reset triggers.
36 poly_mask reset_mask = getResetMask(kReset);
37 position_ = utils::maskLoad(position_, 0.0f, reset_mask);
38
39 // If not forcing portamento, consider the number of notes pressed.
40 if (!force) {
41 poly_float num_voices = input(kNumNotesPressed)->at(0);
42 reset_mask = reset_mask & poly_float::equal(num_voices, 1.0f);
43 position_ = utils::maskLoad(position_, 1.0f, reset_mask);
44 }
45
46 poly_float target = input(kTarget)->at(0);
47 poly_float source = input(kSource)->at(0);
48
49 // If scaling is enabled, adjust the run_seconds based on pitch interval.
50 if (input(kPortamentoScale)->at(0)[0]) {
51 poly_float midi_delta = poly_float::abs(target - source);
52 // Adjust run time by interval in octaves (or notes), defined in kNotesPerOctave.
53 run_seconds *= midi_delta * (1.0f / kNotesPerOctave);
54 }
55
56 // Compute how much to move per sample.
57 poly_float position_delta = poly_float(1.0f * num_samples) / (run_seconds * getSampleRate());
58 position_ = utils::clamp(position_ + position_delta, 0.0f, 1.0f);
59
60 // Apply power scaling to the position if a slope power is provided.
61 poly_float power = -input(kSlopePower)->at(0);
62 poly_float adjusted_position = futils::powerScale(position_, power);
63
64 // Interpolate between source and target based on adjusted position.
65 output()->buffer[0] = utils::interpolate(source, target, adjusted_position);
66 }
67} // namespace vital
virtual void process(int num_samples) override
Processes the portamento over the given number of samples.
Definition portamento_slope.cpp:23
@ kRunSeconds
Duration of portamento in seconds input index.
Definition portamento_slope.h:47
@ kPortamentoScale
Scale portamento by interval input index.
Definition portamento_slope.h:46
@ kNumNotesPressed
Number of notes currently pressed input index.
Definition portamento_slope.h:50
@ kSlopePower
Power/curve of the slope input index.
Definition portamento_slope.h:48
@ kSource
Source value input index.
Definition portamento_slope.h:44
@ kReset
Reset trigger input index.
Definition portamento_slope.h:49
@ kTarget
Target value input index.
Definition portamento_slope.h:43
@ kPortamentoForce
Force portamento on/off input index.
Definition portamento_slope.h:45
void processBypass(int start)
Processes a block when the portamento is effectively bypassed.
Definition portamento_slope.cpp:16
PortamentoSlope()
Constructs a new PortamentoSlope processor.
Definition portamento_slope.cpp:12
static constexpr float kMinPortamentoTime
Minimum portamento time in seconds.
Definition portamento_slope.h:36
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 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
Contains faster but less accurate versions of utility math functions, such as exponential,...
force_inline mono_float powerScale(mono_float value, mono_float power)
A power-scaling function to map a linear range to a curved response.
Definition futils.h:455
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 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.
constexpr int kNotesPerOctave
Number of semitones per octave.
Definition common.h:51
Declares the PortamentoSlope class, which applies a portamento transition between a source and target...
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
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600
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 simd_type vector_call abs(simd_type value)
Computes the absolute value of each element in the SIMD float register.
Definition poly_values.h:935
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
Provides various utility functions, classes, and constants for audio, math, and general-purpose opera...