Sound Byte Libs 0.5.1-121-g3358a44
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
interpolate.hpp
Go to the documentation of this file.
1// sbl/dsp/interpolate.hpp — Interpolation and blending utilities
2//
3// Named functions for common DSP operations that are trivial to write
4// inline but benefit from standardized, readable names.
5//
6// Usage:
7// float mix = sbl::dsp::math::crossfade(dry, wet, 0.5f); // 50/50 blend
8// float smooth = sbl::dsp::math::smooth_step(t); // S-curve [0,1]
9
10#ifndef SBL_DSP_MATH_INTERPOLATE_HPP_
11#define SBL_DSP_MATH_INTERPOLATE_HPP_
12
13#include <cstdint>
14#include <cmath>
15
16namespace sbl::dsp::math {
17
18/**
19 * @brief Linear crossfade between two values
20 *
21 * @param a Value at t=0
22 * @param b Value at t=1
23 * @param t Blend factor [0.0, 1.0]
24 * @return a + (b - a) * t
25 */
26inline constexpr float crossfade(float a, float b, float t) {
27 return a + (b - a) * t;
28}
29
30/**
31 * @brief Hermite smooth step (3rd-order S-curve)
32 *
33 * Maps [0, 1] → [0, 1] with zero derivative at endpoints.
34 * Useful for equal-power-like crossfade curves, smooth transitions,
35 * and perceptually linear parameter morphing.
36 *
37 * @param t Input [0.0, 1.0] (not clamped)
38 * @return t² × (3 - 2t)
39 */
40inline constexpr float smooth_step(float t) {
41 return t * t * (3.0f - 2.0f * t);
42}
43
44/**
45 * @brief Integer crossfade for 16-bit values
46 *
47 * @param a Value at t=0
48 * @param b Value at t=1
49 * @param t Blend factor [0, 65535] (0 = all a, 65535 = all b)
50 * @return Blended value
51 */
52inline constexpr int32_t crossfade_i16(int16_t a, int16_t b, uint16_t t) {
53 return a + ((static_cast<int32_t>(b) - a) * t) / 65535;
54}
55
56// ─── Equal-power crossfade ───────────────────────────────────────────
57
58/**
59 * @brief Equal-power crossfade between two values
60 *
61 * Maintains constant power across the fade (no dip at t=0.5).
62 * Uses sqrt approximation: a*sqrt(1-t) + b*sqrt(t).
63 *
64 * @param a Value at t=0 (dry)
65 * @param b Value at t=1 (wet)
66 * @param t Blend factor [0.0, 1.0]
67 */
68inline float crossfade_equal_power(float a, float b, float t) {
69 return a * sqrtf(1.0f - t) + b * sqrtf(t);
70}
71
72// ─── Block crossfade (constant mix) ─────────────────────────────────
73
74/**
75 * @brief Linear crossfade over a block with constant mix
76 *
77 * out[i] = a[i] * (1-mix) + b[i] * mix. In-place safe (out can alias a or b).
78 */
79inline void crossfade_block(const float* a, const float* b,
80 float* out, float mix, uint16_t frames) {
81 const float ga = 1.0f - mix;
82 for (uint16_t i = 0; i < frames; ++i) {
83 out[i] = a[i] * ga + b[i] * mix;
84 }
85}
86
87/**
88 * @brief Equal-power crossfade over a block with constant mix
89 *
90 * out[i] = a[i] * sqrt(1-mix) + b[i] * sqrt(mix). Gains computed once.
91 */
92inline void crossfade_block_equal_power(const float* a, const float* b,
93 float* out, float mix, uint16_t frames) {
94 const float ga = sqrtf(1.0f - mix);
95 const float gb = sqrtf(mix);
96 for (uint16_t i = 0; i < frames; ++i) {
97 out[i] = a[i] * ga + b[i] * gb;
98 }
99}
100
101} // namespace sbl::dsp::math
102
103#endif // SBL_DSP_MATH_INTERPOLATE_HPP_
Cross-cutting math used at every audio layer.
Definition clamp.hpp:10
float crossfade_equal_power(float a, float b, float t)
Equal-power crossfade between two values.
void crossfade_block(const float *a, const float *b, float *out, float mix, uint16_t frames)
Linear crossfade over a block with constant mix.
constexpr float smooth_step(float t)
Hermite smooth step (3rd-order S-curve)
void crossfade_block_equal_power(const float *a, const float *b, float *out, float mix, uint16_t frames)
Equal-power crossfade over a block with constant mix.
constexpr int32_t crossfade_i16(int16_t a, int16_t b, uint16_t t)
Integer crossfade for 16-bit values.
constexpr float crossfade(float a, float b, float t)
Linear crossfade between two values.