Sound Byte Libs 29c5ff3
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#pragma once
21
22#include <cstdint>
23#include <cmath>
24
26
27/**
28 * @brief Stereo pan gains (float)
29 *
30 * Gains are 0.0–1.0 where 0 = silence and 1.0 = unity.
31 * Computed via constant-power pan law: L^2 + R^2 = 1.
32 */
33struct PanGain {
34 float left;
35 float right;
36};
37
38/**
39 * @brief Compute constant-power pan gains (-3 dB at center)
40 *
41 * Uses sqrt-based constant-power pan law:
42 * L = sqrt(1 - p), R = sqrt(p)
43 *
44 * This ensures L^2 + R^2 = 1 for any position, maintaining
45 * constant power across the stereo field.
46 *
47 * @param position Pan position: 0.0 = hard left, 0.5 = center, 1.0 = hard right
48 * @return PanGain with left and right gains [0.0, 1.0]
49 *
50 * @note Uses sqrtf internally. Intended for init-time precomputation,
51 * not per-sample use. On Cortex-M7 with FPU, cost is ~10 cycles.
52 */
53inline PanGain constant_power(float position) {
54 float p = position;
55 if (p < 0.0f) p = 0.0f;
56 if (p > 1.0f) p = 1.0f;
57 return {
58 sqrtf(1.0f - p),
59 sqrtf(p),
60 };
61}
62
63/**
64 * @brief Apply pan gains to a mono buffer and accumulate into stereo buffers
65 *
66 * Multiplies each mono sample by the left and right gains, and ADDS
67 * the result to the left[] and right[] buffers. Caller must zero the
68 * stereo buffers before the first call when mixing multiple sources.
69 *
70 * @param mono Input mono buffer (read-only)
71 * @param left Left output buffer (accumulated, += semantics)
72 * @param right Right output buffer (accumulated, += semantics)
73 * @param gain Precomputed pan gains from constant_power()
74 * @param frames Number of samples
75 *
76 * @note ISR-safe — bounded computation, no I/O
77 */
78inline void pan_mix(const float* mono, float* left, float* right,
79 PanGain gain, uint16_t frames) {
80 for (uint16_t i = 0; i < frames; ++i) {
81 left[i] += mono[i] * gain.left;
82 right[i] += mono[i] * gain.right;
83 }
84}
85
86} // namespace sbl::dsp::stereo
Stereo panning utilities.
Definition stereo.hpp:25
PanGain constant_power(float position)
Compute constant-power pan gains (-3 dB at center)
Definition stereo.hpp:53
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:78
Stereo pan gains (float)
Definition stereo.hpp:33