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
stereo.hpp
Go to the documentation of this file.
1// sbl/dsp/stereo.hpp — Stereo panning and mixing (Audio Stack — Atoms)
2//
3// Constant-power panning and stereo accumulation for float audio pipelines.
4// All functions are ISR-safe with bounded computation.
5//
6// Usage:
7// // Precompute pan gains (init-time)
8// auto pan_l = sbl::dsp::stereo::constant_power(0.25f); // slightly left
9// auto pan_c = sbl::dsp::stereo::constant_power(0.5f); // center
10// auto pan_r = sbl::dsp::stereo::constant_power(0.75f); // slightly right
11//
12// // In audio callback: mix voices into stereo field
13// float left[48] = {}, right[48] = {};
14// sbl::dsp::stereo::pan_mix(voice1, left, right, pan_l, frames);
15// sbl::dsp::stereo::pan_mix(voice2, left, right, pan_c, frames);
16// sbl::dsp::stereo::pan_mix(voice3, left, right, pan_r, frames);
17//
18// // DMA interleave/deinterleave: see dsp/convert.hpp
19
20#ifndef SBL_DSP_MATH_STEREO_HPP_
21#define SBL_DSP_MATH_STEREO_HPP_
22
23#include <cstdint>
24#include <cmath>
25
27
28/**
29 * @brief Stereo pan gains (float)
30 *
31 * Gains are 0.0–1.0 where 0 = silence and 1.0 = unity.
32 * Computed via constant-power pan law: L^2 + R^2 = 1.
33 */
34struct PanGain {
35 float left;
36 float right;
37};
38
39/**
40 * @brief Compute constant-power pan gains (-3 dB at center)
41 *
42 * Uses sqrt-based constant-power pan law:
43 * L = sqrt(1 - p), R = sqrt(p)
44 *
45 * This ensures L^2 + R^2 = 1 for any position, maintaining
46 * constant power across the stereo field.
47 *
48 * @param position Pan position: 0.0 = hard left, 0.5 = center, 1.0 = hard right
49 * @return PanGain with left and right gains [0.0, 1.0]
50 *
51 * @note Uses sqrtf internally. Intended for init-time precomputation,
52 * not per-sample use. On Cortex-M7 with FPU, cost is ~10 cycles.
53 */
54inline PanGain constant_power(float position) {
55 float p = position;
56 if (p < 0.0f) p = 0.0f;
57 if (p > 1.0f) p = 1.0f;
58 return {
59 sqrtf(1.0f - p),
60 sqrtf(p),
61 };
62}
63
64/**
65 * @brief Apply pan gains to a mono buffer and accumulate into stereo buffers
66 *
67 * Multiplies each mono sample by the left and right gains, and ADDS
68 * the result to the left[] and right[] buffers. Caller must zero the
69 * stereo buffers before the first call when mixing multiple sources.
70 *
71 * @param mono Input mono buffer (read-only)
72 * @param left Left output buffer (accumulated, += semantics)
73 * @param right Right output buffer (accumulated, += semantics)
74 * @param gain Precomputed pan gains from constant_power()
75 * @param frames Number of samples
76 *
77 * @note ISR-safe — bounded computation, no I/O
78 */
79inline void pan_mix(const float* mono, float* left, float* right,
80 PanGain gain, uint16_t frames) {
81 for (uint16_t i = 0; i < frames; ++i) {
82 left[i] += mono[i] * gain.left;
83 right[i] += mono[i] * gain.right;
84 }
85}
86
87} // namespace sbl::dsp::stereo
88
89#endif // SBL_DSP_MATH_STEREO_HPP_
Stereo panning.
Definition stereo.hpp:26
PanGain constant_power(float position)
Compute constant-power pan gains (-3 dB at center)
Definition stereo.hpp:54
void pan_mix(const float *mono, float *left, float *right, PanGain gain, uint16_t frames)
Apply pan gains to a mono buffer and accumulate into stereo buffers.
Definition stereo.hpp:79
Stereo pan gains (float)
Definition stereo.hpp:34