Classes | |
| struct | MinMax |
| Pair returned by find_min_max. More... | |
| struct | PeakRms |
| Block level reading returned by measure_peak_rms: the peak absolute sample value and the root-mean-square level. More... | |
Functions | |
| template<typename Fn> | |
| void | map_samples (const float *in, float *out, std::size_t n, Fn &&fn) |
| Write out[i] = fn(in[i]) for every sample, in index order. | |
| template<std::size_t... Counts, typename Fn> | |
| void | with_channel_count (std::size_t channels, Fn &&fn) |
| Call fn once with the channel count, as a compile-time constant when it is one of Counts... and as a runtime std::size_t otherwise. | |
| void | apply_gain (std::span< float > samples, float gain) |
| Apply a constant gain to a single channel of samples in place. | |
| void | apply_gain (BufferView< float > buffer, float gain) |
| Apply a constant gain to every channel of a multi-channel buffer. | |
| void | apply_gain_ramp (std::span< float > samples, float start_gain, float end_gain) |
| Apply a linear gain ramp from start_gain to end_gain across the span. | |
| void | apply_gain_ramp (BufferView< float > buffer, float start_gain, float end_gain) |
| Apply the same gain ramp to every channel of a multi-channel buffer. | |
| void | clip (std::span< float > samples, float lo, float hi) |
| Hard-clip every sample to [lo, hi] in place. | |
| void | clip (BufferView< float > buffer, float lo, float hi) |
| Hard-clip every channel of a multi-channel buffer to [lo, hi]. | |
| MinMax | find_min_max (std::span< const float > samples) |
| Find the min and max sample values in a span. | |
| MinMax | find_min_max (const BufferView< float > &buffer, std::size_t channel) |
| Find the min and max for one channel of a multi-channel buffer. | |
| MinMax | find_min_max (const BufferView< const float > &buffer, std::size_t channel) |
| float | find_magnitude (std::span< const float > samples) |
| Find the peak absolute value (magnitude) in a span. | |
| float | find_magnitude (const BufferView< float > &buffer, std::size_t channel) |
| Find the peak absolute value across one channel of a multi-channel buffer. | |
| float | find_magnitude (const BufferView< const float > &buffer, std::size_t channel) |
| PeakRms | measure_peak_rms (std::span< const float > samples) noexcept |
| Measure the peak absolute value and RMS of a block in one pass. | |
| PeakRms | measure_peak_rms (const BufferView< float > &buffer, std::size_t channel) noexcept |
| Measure one channel of a multi-channel buffer. | |
| PeakRms | measure_peak_rms (const BufferView< const float > &buffer, std::size_t channel) noexcept |
Variables | |
| constexpr std::size_t | kPeakRmsLanes = 16 |
| Number of independent partial sums measure_peak_rms keeps. | |
| void pulp::audio::buffer_ops::apply_gain | ( | BufferView< float > | buffer, |
| float | gain ) |
Apply a constant gain to every channel of a multi-channel buffer.
| void pulp::audio::buffer_ops::apply_gain | ( | std::span< float > | samples, |
| float | gain ) |
Apply a constant gain to a single channel of samples in place.
| void pulp::audio::buffer_ops::apply_gain_ramp | ( | BufferView< float > | buffer, |
| float | start_gain, | ||
| float | end_gain ) |
Apply the same gain ramp to every channel of a multi-channel buffer.
| void pulp::audio::buffer_ops::apply_gain_ramp | ( | std::span< float > | samples, |
| float | start_gain, | ||
| float | end_gain ) |
Apply a linear gain ramp from start_gain to end_gain across the span.
The ramp is sample-accurate: samples[0] is multiplied by start_gain, samples[N-1] by end_gain, with (end - start) / (N - 1) step between adjacent samples (or start for a 1-sample span). A 0-length span is a no-op.
| void pulp::audio::buffer_ops::clip | ( | BufferView< float > | buffer, |
| float | lo, | ||
| float | hi ) |
Hard-clip every channel of a multi-channel buffer to [lo, hi].
| void pulp::audio::buffer_ops::clip | ( | std::span< float > | samples, |
| float | lo, | ||
| float | hi ) |
Hard-clip every sample to [lo, hi] in place.
NaN inputs become lo (matches the audio convention of treating non-finite samples as silence rather than letting them propagate).
| float pulp::audio::buffer_ops::find_magnitude | ( | const BufferView< const float > & | buffer, |
| std::size_t | channel ) |
| float pulp::audio::buffer_ops::find_magnitude | ( | const BufferView< float > & | buffer, |
| std::size_t | channel ) |
Find the peak absolute value across one channel of a multi-channel buffer.
| float pulp::audio::buffer_ops::find_magnitude | ( | std::span< const float > | samples | ) |
Find the peak absolute value (magnitude) in a span.
Empty span yields 0.0f.
Built from the SIMD min/max reductions, so a NaN anywhere in the span can make the result NaN (it does on the Apple backend). That differs from measure_peak_rms().peak, which ignores NaN samples; use that one for a meter that must keep reading through a stray NaN.
| MinMax pulp::audio::buffer_ops::find_min_max | ( | const BufferView< const float > & | buffer, |
| std::size_t | channel ) |
| MinMax pulp::audio::buffer_ops::find_min_max | ( | const BufferView< float > & | buffer, |
| std::size_t | channel ) |
Find the min and max for one channel of a multi-channel buffer.
| MinMax pulp::audio::buffer_ops::find_min_max | ( | std::span< const float > | samples | ) |
Find the min and max sample values in a span.
Empty span yields {0, 0}.
|
inline |
Write out[i] = fn(in[i]) for every sample, in index order.
This is the per-sample loop a processor writes for a stateless or in-order stateful sample function (gain, mix, a waveshaper), written so it vectorizes whether or not the host processes in place. A plain out[i] = f(in[i]) loop compiles to a runtime overlap check, and out == in — the usual in-place call — fails that check and runs the scalar fallback. Here the in-place case is its own single-pointer loop, which the compiler can vectorize without a check.
in and out must be the same pointer or not overlap. fn is called exactly once per sample, in increasing index order, so a function that carries state from one sample to the next still sees samples in order.
|
noexcept |
|
noexcept |
Measure one channel of a multi-channel buffer.
|
noexcept |
Measure the peak absolute value and RMS of a block in one pass.
This is the per-block meter reading a processor publishes for its UI. It is allocation-free, safe on the audio thread, and vectorizes: independent partial sums break the serial add chain a naive sum += x * x loop forms. RMS is sqrt(sum_of_squares / size).
Non-finite input: a NaN sample, quiet or signaling, is ignored by peak (the same result as folding with std::max(peak, std::abs(x))) but propagates to rms, so a NaN in the block still shows up in the reading. An infinite sample makes both values infinite.
|
inline |
Call fn once with the channel count, as a compile-time constant when it is one of Counts... and as a runtime std::size_t otherwise.
A sample-outer loop over a runtime channel count (for i … for ch < channels) cannot be unrolled across channels, so per-channel state is re-addressed every sample and independent channel work is not overlapped. Dispatching once per block lets the common layouts compile with a constant count while any other count still runs:
count is a std::integral_constant<std::size_t, N> for a listed count, which converts to std::size_t, so the same generic lambda body serves both.
|
inlineconstexpr |
Number of independent partial sums measure_peak_rms keeps.
Sample i is accumulated into partial i % kPeakRmsLanes; the partials are then combined pairwise (lane k with lane k + 8, then k with k + 4, k + 2, and finally 0 with 1). The order is fixed rather than tied to the host's SIMD width, so builds that make the same FMA-contraction choice for sum + x * x agree bit for bit; rms can differ in the last bit between builds that do and do not contract it (the per-compiler policy is in tools/cmake/PulpFloatingPointContraction.cmake). peak is always identical.