Vital
Loading...
Searching...
No Matches
peak_meter.cpp
Go to the documentation of this file.
1
6#include "peak_meter.h"
7#include "utils.h"
8#include "synth_constants.h"
9
10namespace vital {
11
12 namespace {
14 constexpr mono_float kSampleDecay = 8096.0f;
16 constexpr mono_float kRememberedDecay = 20000.0f;
18 constexpr mono_float kRememberedHold = 50000.0f;
19 } // namespace
20
22 Processor(1, 2),
23 current_peak_(0.0f),
24 current_square_sum_(0.0f),
25 remembered_peak_(0.0f),
26 samples_since_remembered_(0) { }
27
28 void PeakMeter::process(int num_samples) {
29 // Get input audio buffer.
30 const poly_float* audio_in = input(0)->source->buffer;
31
32 // Compute peak value of the current block.
33 poly_float peak = utils::peak(audio_in, num_samples);
34
35 // Compute sample-based decay rates depending on oversampling.
36 mono_float samples = getOversampleAmount() * kSampleDecay;
37 mono_float mult = (samples - 1.0f) / samples;
38 poly_float current_peak = current_peak_;
39
40 mono_float remembered_samples = getOversampleAmount() * kRememberedDecay;
41 mono_float remembered_mult = (remembered_samples - 1.0f) / remembered_samples;
42 poly_float current_remembered_peak = remembered_peak_;
43
44 poly_float current_square_sum = current_square_sum_;
45
46 // Apply decay to peak and remembered peak, accumulate squared samples.
47 for (int i = 0; i < num_samples; ++i) {
48 current_peak *= mult;
49 current_remembered_peak *= remembered_mult;
50 current_square_sum *= mult;
51 poly_float sample = audio_in[i];
52 current_square_sum += sample * sample;
53 }
54
55 current_peak_ = utils::max(current_peak, peak);
56 samples_since_remembered_ += num_samples;
57
58 // Update remembered peak logic:
59 // If the current peak is less than the remembered peak, we keep counting samples since remembered.
61
62 mono_float remembered_hold_samples = getOversampleAmount() * kRememberedHold;
63 poly_mask hold_mask = poly_int::lessThan(samples_since_remembered_, remembered_hold_samples);
64 current_remembered_peak = utils::maskLoad(current_remembered_peak, remembered_peak_, hold_mask);
65
66 remembered_peak_ = utils::max(current_peak_, current_remembered_peak);
67 current_square_sum_ = current_square_sum;
68
69 // Compute RMS as needed (though here we just store info).
70 poly_float rms = utils::sqrt(current_square_sum_ * (1.0f / samples));
71 poly_float prepped_rms = utils::swapVoices(rms);
72
73 // Write outputs: current peak and remembered peak.
76 }
77} // namespace vital
poly_float current_square_sum_
Sum of squared samples used for RMS/level calculations.
Definition peak_meter.h:65
poly_float remembered_peak_
The highest remembered peak level over a certain period.
Definition peak_meter.h:68
poly_int samples_since_remembered_
The number of samples since the remembered peak was updated.
Definition peak_meter.h:71
PeakMeter()
Constructs a new PeakMeter processor.
Definition peak_meter.cpp:21
poly_float current_peak_
Current instantaneous peak value.
Definition peak_meter.h:62
@ kMemoryPeak
Memory-peak output index.
Definition peak_meter.h:38
@ kLevel
Current peak output index.
Definition peak_meter.h:37
void process(int num_samples) override
Processes the input audio to compute current and remembered peak levels.
Definition peak_meter.cpp:28
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 getOversampleAmount() const
Retrieves the current oversampling factor.
Definition processor.h:334
force_inline Output * output(unsigned int index=0) const
Retrieves the Output pointer at a given index.
Definition processor.h:616
const poly_mask kFirstMask
A mask identifying the first voice slots in a polyphonic vector.
Definition synth_constants.h:266
force_inline poly_float peak(const poly_float *buffer, int num, int skip=1)
Returns the peak magnitude of a buffer (considering both positive and negative values).
Definition poly_utils.h:557
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 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 sqrt(poly_float value)
Computes the square root of each element in a poly_float.
Definition poly_utils.h:169
Contains classes and functions used within the Vital synthesizer framework.
float mono_float
Definition common.h:33
Defines the PeakMeter class, a processor that measures and reports peak and memory-peak levels of aud...
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 poly_mask vector_call lessThan(poly_float one, poly_float two)
Definition poly_values.h:1105
Represents a vector of integer values using SIMD instructions.
Definition poly_values.h:56
static force_inline poly_int vector_call lessThan(poly_int one, poly_int two)
Definition poly_values.h:378
Provides various utility functions, classes, and constants for audio, math, and general-purpose opera...