Sound Byte Libs 29c5ff3
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
noise.hpp
Go to the documentation of this file.
1// sbl/widgets/source/noise.hpp — Noise generator (Audio Stack — Widgets)
2//
3// White noise via Galois LFSR (maximal-length 32-bit).
4// Pink noise via Paul Kellet's single-pole IIR filter bank.
5//
6// Usage:
7// sbl::widgets::source::Noise noise;
8// noise.set_color(NoiseColor::Pink);
9// noise.process(buf, frames);
10
11#pragma once
12
13#include <cstdint>
14
16
17enum class NoiseColor : uint8_t {
18 White,
19 Pink,
20};
21
22class Noise {
23public:
24 /// @note All public methods are ISR-safe — bounded computation, no I/O.
25
26 /** @brief Set noise color */
27 void set_color(NoiseColor c) { color_ = c; }
28
29 /** @brief Set output amplitude (0.0 = silence, 1.0 = full scale) */
30 void set_amplitude(float amp) { amplitude_ = amp; }
31
32 /**
33 * @brief Generate noise samples
34 * @param out Output buffer (float, [-1.0, 1.0])
35 * @param frames Number of samples
36 */
37 void process(float* out, uint16_t frames) {
38 for (uint16_t i = 0; i < frames; ++i) {
39 float white = next_white();
40
41 if (color_ == NoiseColor::Pink) {
42 out[i] = pink_filter(white) * amplitude_;
43 } else {
44 out[i] = white * amplitude_;
45 }
46 }
47 }
48
49 /** @brief Seed the LFSR (for reproducible output in tests) */
50 void seed(uint32_t s) { lfsr_ = s ? s : 1; }
51
52private:
54 float amplitude_ = 1.0f;
55
56 // Galois LFSR — 32-bit maximal length (taps: 32, 22, 2, 1)
57 uint32_t lfsr_ = 0x12345678u;
58
59 // Paul Kellet pink noise filter state
60 float b0_ = 0, b1_ = 0, b2_ = 0, b3_ = 0, b4_ = 0, b5_ = 0, b6_ = 0;
61
62 float next_white() {
63 // Galois LFSR: if LSB set, XOR with polynomial
64 uint32_t lsb = lfsr_ & 1u;
65 lfsr_ >>= 1;
66 if (lsb) lfsr_ ^= 0xD0000001u; // Maximal-length polynomial
67 // Convert to float [-1.0, 1.0]
68 return (static_cast<float>(lfsr_) / 2147483648.0f) - 1.0f;
69 }
70
71 float pink_filter(float white) {
72 // Paul Kellet's economy method (7 state variables)
73 // Spectral density falls at ~3 dB/octave
74 b0_ = 0.99886f * b0_ + white * 0.0555179f;
75 b1_ = 0.99332f * b1_ + white * 0.0750759f;
76 b2_ = 0.96900f * b2_ + white * 0.1538520f;
77 b3_ = 0.86650f * b3_ + white * 0.3104856f;
78 b4_ = 0.55000f * b4_ + white * 0.5329522f;
79 b5_ = -0.7616f * b5_ + white * 0.0168980f;
80 float pink = b0_ + b1_ + b2_ + b3_ + b4_ + b5_ + b6_ + white * 0.5362f;
81 b6_ = white * 0.115926f;
82
83 // Normalize (pink sum is roughly ±3.5)
84 pink *= 0.11f;
85 if (pink > 1.0f) pink = 1.0f;
86 if (pink < -1.0f) pink = -1.0f;
87
88 return pink;
89 }
90};
91
92} // namespace sbl::widgets::source
void set_color(NoiseColor c)
Set noise color.
Definition noise.hpp:27
void process(float *out, uint16_t frames)
Generate noise samples.
Definition noise.hpp:37
void set_amplitude(float amp)
Set output amplitude (0.0 = silence, 1.0 = full scale)
Definition noise.hpp:30
void seed(uint32_t s)
Seed the LFSR (for reproducible output in tests)
Definition noise.hpp:50
Sound source widgets.
Definition noise.hpp:15