Vital
Loading...
Searching...
No Matches
compressor.cpp
Go to the documentation of this file.
1#include "compressor.h"
2#include "futils.h"
3
4namespace vital {
5
6 namespace {
10 constexpr mono_float kRmsTime = 0.025f;
11
15 constexpr mono_float kMaxExpandMult = 32.0f;
16
20 constexpr mono_float kLowAttackMs = 2.8f;
21 constexpr mono_float kBandAttackMs = 1.4f;
22 constexpr mono_float kHighAttackMs = 0.7f;
23
27 constexpr mono_float kLowReleaseMs = 40.0f;
28 constexpr mono_float kBandReleaseMs = 28.0f;
29 constexpr mono_float kHighReleaseMs = 15.0f;
30
34 constexpr mono_float kMinGain = -30.0f;
35 constexpr mono_float kMaxGain = 30.0f;
36
40 constexpr mono_float kMinThreshold = -100.0f;
41 constexpr mono_float kMaxThreshold = 12.0f;
42
46 constexpr mono_float kMinSampleEnvelope = 5.0f;
47 } // namespace
48
49 //============================================================================
50 //
51 // Compressor
52 //
53 //============================================================================
54
60 Compressor::Compressor(mono_float base_attack_ms_first,
61 mono_float base_release_ms_first,
62 mono_float base_attack_ms_second,
63 mono_float base_release_ms_second)
64 : Processor(kNumInputs, kNumOutputs),
65 input_mean_squared_(0.0f) {
66 // Use maskLoad to selectively load attack/release for voice 1 or voice 2
67 base_attack_ms_ = utils::maskLoad(poly_float(base_attack_ms_second),
68 base_attack_ms_first,
70 poly_float second_release = base_release_ms_second;
71 base_release_ms_ = utils::maskLoad(second_release,
72 base_release_ms_first,
74 output_mult_ = 0.0f;
75 mix_ = 0.0f;
76 }
77
83 void Compressor::process(int num_samples) {
84 processWithInput(input(kAudio)->source->buffer, num_samples);
85 }
86
95 void Compressor::processWithInput(const poly_float* audio_in, int num_samples) {
96 processRms(audio_in, num_samples);
97
98 // Update RMS for input/output signals
101 scaleOutput(audio_in, num_samples);
102 }
103
110 void Compressor::processRms(const poly_float* audio_in, int num_samples) {
111 poly_float* audio_out = output(kAudioOut)->buffer;
112
113 // Convert ms to samples
114 mono_float samples_per_ms = (1.0f * getSampleRate()) / kMsPerSec;
115 poly_float attack_mult = base_attack_ms_ * samples_per_ms;
116 poly_float release_mult = base_release_ms_ * samples_per_ms;
117
118 // Convert 0..1 from GUI to an exponential in the range [-4, 4], then map to sample-based envelope
119 poly_float attack_exponent = utils::clamp(input(kAttack)->at(0), 0.0f, 1.0f) * 8.0f - 4.0f;
120 poly_float release_exponent = utils::clamp(input(kRelease)->at(0), 0.0f, 1.0f) * 8.0f - 4.0f;
121 poly_float envelope_attack_samples = futils::exp(attack_exponent) * attack_mult;
122 poly_float envelope_release_samples = futils::exp(release_exponent) * release_mult;
123
124 // Ensure a minimum envelope length
125 envelope_attack_samples = utils::max(envelope_attack_samples, kMinSampleEnvelope);
126 envelope_release_samples = utils::max(envelope_release_samples, kMinSampleEnvelope);
127
128 // Compute scales for attack/release
129 poly_float attack_scale = poly_float(1.0f) / (envelope_attack_samples + 1.0f);
130 poly_float release_scale = poly_float(1.0f) / (envelope_release_samples + 1.0f);
131
132 // Load and convert thresholds from dB to linear magnitude squared
133 poly_float upper_threshold = utils::clamp(input(kUpperThreshold)->at(0), kMinThreshold, kMaxThreshold);
134 upper_threshold = futils::dbToMagnitude(upper_threshold);
135 upper_threshold *= upper_threshold;
136
137 poly_float lower_threshold = utils::clamp(input(kLowerThreshold)->at(0), kMinThreshold, kMaxThreshold);
138 lower_threshold = futils::dbToMagnitude(lower_threshold);
139 lower_threshold *= lower_threshold;
140
141 // Load compression/expansion ratios
142 poly_float upper_ratio = utils::clamp(input(kUpperRatio)->at(0), 0.0f, 1.0f) * 0.5f;
143 poly_float lower_ratio = utils::clamp(input(kLowerRatio)->at(0), -1.0f, 1.0f) * 0.5f;
144
145 poly_float low_enveloped_mean_squared = low_enveloped_mean_squared_;
146 poly_float high_enveloped_mean_squared = high_enveloped_mean_squared_;
147
148 for (int i = 0; i < num_samples; ++i) {
149 poly_float sample = audio_in[i];
150 poly_float sample_squared = sample * sample;
151
152 // Update high band envelope
153 poly_mask high_attack_mask = poly_float::greaterThan(sample_squared, high_enveloped_mean_squared);
154 poly_float high_samples = utils::maskLoad(envelope_release_samples, envelope_attack_samples, high_attack_mask);
155 poly_float high_scale = utils::maskLoad(release_scale, attack_scale, high_attack_mask);
156 high_enveloped_mean_squared = (sample_squared + high_enveloped_mean_squared * high_samples) * high_scale;
157 high_enveloped_mean_squared = utils::max(high_enveloped_mean_squared, upper_threshold);
158
159 // Compute compression above upper threshold
160 poly_float upper_mag_delta = upper_threshold / high_enveloped_mean_squared;
161 poly_float upper_mult = futils::pow(upper_mag_delta, upper_ratio);
162
163 // Update low band envelope
164 poly_mask low_attack_mask = poly_float::greaterThan(sample_squared, low_enveloped_mean_squared);
165 poly_float low_samples = utils::maskLoad(envelope_release_samples, envelope_attack_samples, low_attack_mask);
166 poly_float low_scale = utils::maskLoad(release_scale, attack_scale, low_attack_mask);
167 low_enveloped_mean_squared = (sample_squared + low_enveloped_mean_squared * low_samples) * low_scale;
168 low_enveloped_mean_squared = utils::min(low_enveloped_mean_squared, lower_threshold);
169
170 // Compute expansion below lower threshold
171 poly_float lower_mag_delta = lower_threshold / low_enveloped_mean_squared;
172 poly_float lower_mult = futils::pow(lower_mag_delta, lower_ratio);
173
174 // Combine gain multipliers and clamp
175 poly_float gain_compression = utils::clamp(upper_mult * lower_mult, 0.0f, kMaxExpandMult);
176 audio_out[i] = gain_compression * sample;
177
178 VITAL_ASSERT(utils::isContained(audio_out[i]));
179 }
180
181 // Save updated envelopes
182 low_enveloped_mean_squared_ = low_enveloped_mean_squared;
183 high_enveloped_mean_squared_ = high_enveloped_mean_squared;
184 }
185
192 void Compressor::scaleOutput(const poly_float* audio_input, int num_samples) {
193 poly_float* audio_out = output(kAudioOut)->buffer;
194
195 // Interpolate output gain changes
196 poly_float current_output_mult = output_mult_;
197 poly_float gain = utils::clamp(input(kOutputGain)->at(0), kMinGain, kMaxGain);
199 poly_float delta_output_mult = (output_mult_ - current_output_mult) * (1.0f / num_samples);
200
201 // Interpolate mix changes
202 poly_float current_mix = mix_;
203 mix_ = utils::clamp(input(kMix)->at(0), 0.0f, 1.0f);
204 poly_float delta_mix = (mix_ - current_mix) * (1.0f / num_samples);
205
206 for (int i = 0; i < num_samples; ++i) {
207 current_output_mult += delta_output_mult;
208 current_mix += delta_mix;
209
210 // Blend dry (audio_input) and wet (compressed audio_out * current_output_mult)
211 audio_out[i] = utils::interpolate(audio_input[i], audio_out[i] * current_output_mult, current_mix);
212
213 VITAL_ASSERT(utils::isContained(audio_out[i]));
214 }
215 }
216
222 void Compressor::reset(poly_mask reset_mask) {
223 input_mean_squared_ = 0.0f;
225 output_mult_ = 0.0f;
226 mix_ = 0.0f;
229 }
230
240 int num_samples,
241 poly_float mean_squared) {
242 int rms_samples = kRmsTime * getSampleRate();
243 float rms_adjusted = rms_samples - 1.0f;
244 mono_float input_scale = 1.0f / rms_samples;
245
246 for (int i = 0; i < num_samples; ++i) {
247 poly_float sample = audio_in[i];
248 poly_float sample_squared = sample * sample;
249 mean_squared = (mean_squared * rms_adjusted + sample_squared) * input_scale;
250 }
251 return mean_squared;
252 }
253
254 //============================================================================
255 //
256 // MultibandCompressor
257 //
258 //============================================================================
259
265 : Processor(kNumInputs, kNumOutputs),
266 low_band_filter_(120.0f),
267 band_high_filter_(2500.0f),
268 low_band_compressor_(kLowAttackMs, kLowReleaseMs, kBandAttackMs, kBandReleaseMs),
269 band_high_compressor_(kBandAttackMs, kBandReleaseMs, kHighAttackMs, kHighReleaseMs) {
270 was_low_enabled_ = false;
271 was_high_enabled_ = false;
272
273 // Connect band thresholds/ratios to the low band compressor
282
283 // Connect band thresholds/ratios to the band+high compressor
292 }
293
306
313 Processor::setSampleRate(sample_rate);
314 low_band_filter_.setSampleRate(sample_rate);
315 band_high_filter_.setSampleRate(sample_rate);
318 }
319
326 low_band_filter_.reset(reset_mask);
327 band_high_filter_.reset(reset_mask);
328 low_band_compressor_.reset(reset_mask);
329 band_high_compressor_.reset(reset_mask);
330
331 // Reset output buffers for RMS displays
338 }
339
345 void MultibandCompressor::process(int num_samples) {
346 processWithInput(input(kAudio)->source->buffer, num_samples);
347 }
348
359 const poly_float* low_output = filter->output(LinkwitzRileyFilter::kAudioLow)->buffer;
360 const poly_float* high_output = filter->output(LinkwitzRileyFilter::kAudioHigh)->buffer;
361
362 for (int i = 0; i < num_samples; ++i) {
363 poly_float low_sample = low_output[i];
364 poly_float high_sample = utils::swapVoices(high_output[i]);
365 dest[i] = utils::maskLoad(high_sample, low_sample, constants::kFirstMask);
366 }
367 }
368
378
379 for (int i = 0; i < num_samples; ++i) {
380 poly_float low_band_sample = low_output[i];
381 poly_float low_high_sample = high_output[i] & constants::kFirstMask;
382 dest[i] = low_band_sample + low_high_sample;
383 }
384 }
385
397
398 for (int i = 0; i < num_samples; ++i) {
399 // Sum left/right voices for low band and high band separately
400 poly_float low_band_sample = low_band_output[i];
401 low_band_sample += utils::swapVoices(low_band_sample);
402 poly_float high_sample = utils::swapVoices(high_output[i]);
403 dest[i] = low_band_sample + high_sample;
404 }
405 }
406
415 void MultibandCompressor::writeCompressorOutputs(Compressor* compressor, int num_samples, poly_float* dest) {
416 const poly_float* compressor_output = compressor->output(Compressor::kAudioOut)->buffer;
417
418 for (int i = 0; i < num_samples; ++i) {
419 poly_float sample = compressor_output[i];
420 dest[i] = sample + utils::swapVoices(sample);
421 }
422 }
423
433 void MultibandCompressor::processWithInput(const poly_float* audio_in, int num_samples) {
434 int enabled_bands = input(kEnabledBands)->at(0)[0];
435 bool low_enabled = (enabled_bands == kMultiband || enabled_bands == kLowBand);
436 bool high_enabled = (enabled_bands == kMultiband || enabled_bands == kHighBand);
437
438 // Retrieve thresholds and ratios from the user inputs, applying them to low or band+high as needed
452 input(kLowUpperRatio)->at(0),
455 input(kBandUpperRatio)->at(0),
458 input(kLowLowerRatio)->at(0),
461 input(kBandLowerRatio)->at(0),
463
465 input(kLowOutputGain)->at(0),
468 input(kBandOutputGain)->at(0),
470
471 // Reset filters/compressors if enabled band configuration changed
472 if (low_enabled != was_low_enabled_ || high_enabled != was_high_enabled_) {
477 was_low_enabled_ = low_enabled;
478 was_high_enabled_ = high_enabled;
479 }
480
481 poly_float* audio_out = output(kAudioOut)->buffer;
482
483 // Full multiband mode: low + band + high
484 if (low_enabled && high_enabled) {
485 // Split signal into low and band+high
486 low_band_filter_.processWithInput(audio_in, num_samples);
487 packFilterOutput(&low_band_filter_, num_samples, audio_out);
488
489 // Split band+high further
490 band_high_filter_.processWithInput(audio_out, num_samples);
491 packLowBandCompressor(num_samples, audio_out);
492
493 // Compress low band
494 low_band_compressor_.processWithInput(audio_out, num_samples);
495
496 // Compress high band
498 band_high_compressor_.processWithInput(band_high_buffer, num_samples);
499
500 // Combine all
501 writeAllCompressorOutputs(num_samples, audio_out);
502 }
503 // Only low band
504 else if (low_enabled) {
505 low_band_filter_.processWithInput(audio_in, num_samples);
506 packFilterOutput(&low_band_filter_, num_samples, audio_out);
507 low_band_compressor_.processWithInput(audio_out, num_samples);
508 writeCompressorOutputs(&low_band_compressor_, num_samples, audio_out);
509 }
510 // Only high band
511 else if (high_enabled) {
512 band_high_filter_.processWithInput(audio_in, num_samples);
513 packFilterOutput(&band_high_filter_, num_samples, audio_out);
514 band_high_compressor_.processWithInput(audio_out, num_samples);
515 writeCompressorOutputs(&band_high_compressor_, num_samples, audio_out);
516 }
517 // Single band, no filter
518 else {
519 band_high_compressor_.processWithInput(audio_in, num_samples);
521 }
522
523 // Write mean squared values for GUI metering
528
529 output(kLowInputMeanSquared)->buffer[0] = low_band_input_ms;
530 output(kLowOutputMeanSquared)->buffer[0] = low_band_output_ms;
531
532 if (low_enabled) {
533 output(kBandInputMeanSquared)->buffer[0] = utils::swapVoices(low_band_input_ms);
534 output(kBandOutputMeanSquared)->buffer[0] = utils::swapVoices(low_band_output_ms);
535 }
536 else {
537 output(kBandInputMeanSquared)->buffer[0] = band_high_input_ms;
538 output(kBandOutputMeanSquared)->buffer[0] = band_high_output_ms;
539 }
540
541 output(kHighInputMeanSquared)->buffer[0] = utils::swapVoices(band_high_input_ms);
542 output(kHighOutputMeanSquared)->buffer[0] = utils::swapVoices(band_high_output_ms);
543 }
544
545} // namespace vital
A dynamic range compressor Processor that operates on a single band of audio.
Definition compressor.h:16
poly_float base_release_ms_
Base release time in ms for the current voice.
Definition compressor.h:165
poly_float input_mean_squared_
Rolling mean squared value of the input signal.
Definition compressor.h:135
Compressor(mono_float base_attack_ms_first, mono_float base_release_ms_first, mono_float base_attack_ms_second, mono_float base_release_ms_second)
Constructs a Compressor Processor with given base attack and release times.
Definition compressor.cpp:60
@ kAudioOut
Compressed audio output.
Definition compressor.h:40
poly_float high_enveloped_mean_squared_
Internal high enveloped mean squared value for upper threshold detection.
Definition compressor.h:145
void processRms(const poly_float *audio_in, int num_samples)
Processes RMS for the input buffer and applies compression gain.
Definition compressor.cpp:110
void scaleOutput(const poly_float *audio_input, int num_samples)
Applies the final output scaling and dry/wet mix to the processed audio.
Definition compressor.cpp:192
poly_float computeMeanSquared(const poly_float *audio_in, int num_samples, poly_float mean_squared)
Computes the mean squared value over a buffer of samples.
Definition compressor.cpp:239
poly_float output_mean_squared_
Rolling mean squared value of the output signal.
Definition compressor.h:140
poly_float low_enveloped_mean_squared_
Internal low enveloped mean squared value for lower threshold detection.
Definition compressor.h:150
poly_float base_attack_ms_
Base attack time in ms for the current voice.
Definition compressor.h:160
void reset(poly_mask reset_mask) override
Resets internal states and envelopes.
Definition compressor.cpp:222
force_inline poly_float getOutputMeanSquared()
Retrieves the current output RMS value (mean squared).
Definition compressor.h:119
virtual void processWithInput(const poly_float *audio_in, int num_samples) override
Processes audio using the provided input buffer and writes to output.
Definition compressor.cpp:95
poly_float mix_
The current dry/wet mix (0.0 = fully dry, 1.0 = fully wet).
Definition compressor.h:155
@ kMix
Dry/Wet mix.
Definition compressor.h:31
@ kUpperRatio
Upper ratio (compression ratio above upper threshold)
Definition compressor.h:26
@ kAudio
Input audio signal.
Definition compressor.h:23
@ kUpperThreshold
Upper threshold in dB.
Definition compressor.h:24
@ kLowerThreshold
Lower threshold in dB.
Definition compressor.h:25
@ kRelease
Release time control (0.0 to 1.0 maps to exponential range)
Definition compressor.h:30
@ kAttack
Attack time control (0.0 to 1.0 maps to exponential range)
Definition compressor.h:29
@ kOutputGain
Output gain (dB)
Definition compressor.h:28
@ kLowerRatio
Lower ratio (expansion ratio below lower threshold)
Definition compressor.h:27
virtual void process(int num_samples) override
Processes audio using the input audio buffer, modifying output buffer in-place.
Definition compressor.cpp:83
poly_float output_mult_
Current multiplier for output gain (converted from dB).
Definition compressor.h:170
force_inline poly_float getInputMeanSquared()
Retrieves the current input RMS value (mean squared).
Definition compressor.h:112
A Linkwitz-Riley crossover filter splitting audio into low and high bands.
Definition linkwitz_riley_filter.h:17
void setOversampleAmount(int oversample_amount) override
Sets the internal oversample amount and recomputes filter coefficients.
Definition linkwitz_riley_filter.cpp:164
void reset(poly_mask reset_mask) override
Resets the internal states (delay lines) for the specified voices.
Definition linkwitz_riley_filter.cpp:173
void processWithInput(const poly_float *audio_in, int num_samples) override
Processes the provided audio input buffer and writes low and high outputs to the Processor’s buffers.
Definition linkwitz_riley_filter.cpp:38
void setSampleRate(int sample_rate) override
Sets the internal sample rate and recomputes filter coefficients.
Definition linkwitz_riley_filter.cpp:155
@ kAudioLow
Low-frequency output.
Definition linkwitz_riley_filter.h:33
@ kAudioHigh
High-frequency output.
Definition linkwitz_riley_filter.h:34
LinkwitzRileyFilter band_high_filter_
A Linkwitz-Riley filter splitting audio into band and high bands.
Definition compressor.h:368
@ kHighOutputMeanSquared
High band output mean squared.
Definition compressor.h:235
@ kLowOutputMeanSquared
Low band output mean squared.
Definition compressor.h:233
@ kBandOutputMeanSquared
Band output mean squared.
Definition compressor.h:234
@ kLowInputMeanSquared
Low band input mean squared.
Definition compressor.h:230
@ kBandInputMeanSquared
Band input mean squared.
Definition compressor.h:231
@ kAudioOut
Combined compressed output.
Definition compressor.h:229
@ kHighInputMeanSquared
High band input mean squared.
Definition compressor.h:232
cr::Output low_band_upper_threshold_
Definition compressor.h:349
@ kHighUpperThreshold
Upper threshold (dB) for high band.
Definition compressor.h:198
@ kLowLowerThreshold
Lower threshold (dB) for low band.
Definition compressor.h:199
@ kEnabledBands
Enabled bands (see BandOptions)
Definition compressor.h:207
@ kHighUpperRatio
Upper ratio for high band.
Definition compressor.h:192
@ kLowUpperThreshold
Upper threshold (dB) for low band.
Definition compressor.h:196
@ kHighLowerThreshold
Lower threshold (dB) for high band.
Definition compressor.h:201
@ kBandUpperRatio
Upper ratio for band.
Definition compressor.h:191
@ kHighOutputGain
Output gain (dB) for high band.
Definition compressor.h:204
@ kBandLowerThreshold
Lower threshold (dB) for band.
Definition compressor.h:200
@ kAttack
Global attack control.
Definition compressor.h:205
@ kLowLowerRatio
Lower ratio for low band.
Definition compressor.h:193
@ kRelease
Global release control.
Definition compressor.h:206
@ kMix
Dry/wet mix for all bands.
Definition compressor.h:208
@ kBandUpperThreshold
Upper threshold (dB) for band.
Definition compressor.h:197
@ kAudio
Input audio signal.
Definition compressor.h:189
@ kBandOutputGain
Output gain (dB) for band.
Definition compressor.h:203
@ kLowUpperRatio
Upper ratio for low band.
Definition compressor.h:190
@ kHighLowerRatio
Lower ratio for high band.
Definition compressor.h:195
@ kLowOutputGain
Output gain (dB) for low band.
Definition compressor.h:202
@ kBandLowerRatio
Lower ratio for band.
Definition compressor.h:194
MultibandCompressor()
Constructs a MultibandCompressor, creating internal compressors and filters.
Definition compressor.cpp:264
void setOversampleAmount(int oversample) override
Sets the amount of oversampling for the internal filters and compressors.
Definition compressor.cpp:299
void setSampleRate(int sample_rate) override
Sets the current sample rate for the internal filters and compressors.
Definition compressor.cpp:312
bool was_high_enabled_
Whether the high band was enabled on the previous process() call.
Definition compressor.h:337
cr::Output band_high_upper_ratio_
Definition compressor.h:346
Compressor band_high_compressor_
Compressor handling band + high, or high only if configured.
Definition compressor.h:378
void packLowBandCompressor(int num_samples, poly_float *dest)
Combines band filter outputs into a single buffer for the low band compressor.
Definition compressor.cpp:375
cr::Output band_high_upper_threshold_
Definition compressor.h:350
virtual void processWithInput(const poly_float *audio_in, int num_samples) override
Processes audio using the given input buffer and writes to output.
Definition compressor.cpp:433
cr::Output low_band_upper_ratio_
Outputs for the low/band compressor thresholds and ratios.
Definition compressor.h:345
void writeCompressorOutputs(Compressor *compressor, int num_samples, poly_float *dest)
Writes a single compressor’s output to a buffer when only one band is active.
Definition compressor.cpp:415
LinkwitzRileyFilter low_band_filter_
A Linkwitz-Riley filter splitting audio into low band and the rest (band + high).
Definition compressor.h:363
void writeAllCompressorOutputs(int num_samples, poly_float *dest)
Writes the combined output of both compressors to a buffer.
Definition compressor.cpp:394
virtual void process(int num_samples) override
Processes audio using the input audio buffer.
Definition compressor.cpp:345
Compressor low_band_compressor_
Compressor handling the low band.
Definition compressor.h:373
bool was_low_enabled_
Whether the low band was enabled on the previous process() call.
Definition compressor.h:332
cr::Output band_high_lower_ratio_
Definition compressor.h:348
cr::Output low_band_lower_ratio_
Definition compressor.h:347
void packFilterOutput(LinkwitzRileyFilter *filter, int num_samples, poly_float *dest)
Extracts the LinkwitzRileyFilter’s output into a combined buffer for further processing.
Definition compressor.cpp:358
void reset(poly_mask reset_mask) override
Resets internal states and filters.
Definition compressor.cpp:325
cr::Output low_band_lower_threshold_
Definition compressor.h:351
cr::Output low_band_output_gain_
Gain controls for low and band/high compressors.
Definition compressor.h:357
cr::Output band_high_output_gain_
Definition compressor.h:358
cr::Output band_high_lower_threshold_
Definition compressor.h:352
@ kHighBand
Only high band active.
Definition compressor.h:219
@ kLowBand
Only low band active.
Definition compressor.h:218
@ kMultiband
All three bands active.
Definition compressor.h:217
Base class for all signal-processing units in Vital.
Definition processor.h:212
virtual void setOversampleAmount(int oversample)
Sets the oversampling amount and updates the effective sample rate.
Definition processor.h:293
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
void useInput(Input *input)
Uses an existing Input object as this Processor's first input.
Definition processor.cpp:126
void plug(const Output *source)
Connects an external Output to this Processor's first input.
Definition processor.cpp:79
force_inline Output * output(unsigned int index=0) const
Retrieves the Output pointer at a given index.
Definition processor.h:616
virtual void setSampleRate(int sample_rate)
Updates the sample rate of this Processor (scaled by oversampling).
Definition processor.h:285
#define VITAL_ASSERT(x)
Definition common.h:11
cr::Value gain
Relative gain for this formant stage.
Definition formant_filter.cpp:17
Contains faster but less accurate versions of utility math functions, such as exponential,...
const poly_mask kFullMask
A mask covering all lanes of a poly_float vector.
Definition synth_constants.h:257
const poly_mask kFirstMask
A mask identifying the first voice slots in a polyphonic vector.
Definition synth_constants.h:266
force_inline mono_float exp(mono_float exponent)
Definition futils.h:132
force_inline mono_float pow(mono_float base, mono_float exponent)
Definition futils.h:141
force_inline mono_float dbToMagnitude(mono_float decibels)
Converts decibels (dB) to magnitude (linear).
Definition futils.h:217
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 min(poly_float left, poly_float right)
Returns the minimum of two poly_floats lane-by-lane.
Definition poly_utils.h:334
force_inline bool isContained(poly_float value)
Checks if all lanes in a poly_float are within a broad range [-8000..8000].
Definition poly_utils.h:631
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 swapVoices(poly_float value)
Swaps the first half of the lanes with the second half.
Definition poly_utils.h:437
force_inline void copyBuffer(mono_float *dest, const mono_float *source, int size)
Copies data from a source mono buffer to a destination mono buffer.
Definition poly_utils.h:586
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 kMsPerSec
Milliseconds per second.
Definition common.h:50
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
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 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