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
phase_accumulator.hpp
Go to the documentation of this file.
1// sbl/dsp/primitives/phase_accumulator.hpp — Phase accumulator for oscillators and LFOs
2//
3// 32-bit phase accumulator with natural wrapping. The full uint32_t range
4// maps to one cycle (0 to just-under-2π). Frequency is set via phase
5// increment per sample.
6//
7// Usage:
8// sbl::dsp::PhaseAccumulator phase;
9// phase.set_increment(PhaseAccumulator::freq_to_inc(440.0f));
10// phase.advance(); // single sample
11// uint32_t p = phase.phase(); // read current phase
12//
13// Block processing:
14// uint32_t buf[BLOCK_SIZE];
15// phase.advance(BLOCK_SIZE, buf); // fill buffer with per-sample phases
16
17#ifndef SBL_DSP_PRIMITIVES_PHASE_ACCUMULATOR_HPP_
18#define SBL_DSP_PRIMITIVES_PHASE_ACCUMULATOR_HPP_
19
20#include <cstdint>
21
24
25namespace sbl::dsp::primitives {
26
27/// Full range of a 32-bit phase accumulator (2^32 as float)
29
31public:
32 /// @note All public methods are ISR-safe — bounded computation, no I/O.
33
34 /**
35 * @brief Set the phase increment per sample
36 *
37 * inc = frequency_hz * 2^32 / sample_rate
38 * Use freq_to_inc() for Hz input.
39 */
40 void set_increment(uint32_t inc) { increment_ = inc; }
41
42 /** @brief Advance phase by one sample */
43 void advance() { phase_ += increment_; }
44
45 /**
46 * @brief Advance and fill a buffer with per-sample phases
47 *
48 * Each output element is the phase AFTER advancing. Useful for
49 * batch wavetable reads.
50 */
51 void advance(uint16_t frames, uint32_t* out) {
52 for (uint16_t i = 0; i < frames; ++i) {
53 phase_ += increment_;
54 out[i] = phase_;
55 }
56 }
57
58 /** @brief Current phase value */
59 uint32_t phase() const { return phase_; }
60
61 /** @brief Current phase increment */
62 uint32_t increment() const { return increment_; }
63
64 /** @brief Reset phase to zero */
65 void reset() { phase_ = 0; }
66
67 /** @brief Reset phase to a specific value (for sync) */
68 void reset(uint32_t phase) { phase_ = phase; }
69
70 /**
71 * @brief Convert frequency in Hz to phase increment
72 *
73 * @param freq_hz Frequency in Hz (e.g., 440.0f)
74 * @param sr Sample rate (default: SAMPLE_RATE_F global)
75 * @return Phase increment per sample
76 */
77 static uint32_t freq_to_inc(float freq_hz, float sr = types::SAMPLE_RATE_F) {
78 return static_cast<uint32_t>((freq_hz / sr) * PHASE_ACCUMULATOR_RANGE);
79 }
80
81private:
82 uint32_t phase_ = 0;
83 uint32_t increment_ = 0;
84};
85
86} // namespace sbl::dsp::primitives
87
88#endif // SBL_DSP_PRIMITIVES_PHASE_ACCUMULATOR_HPP_
void reset(uint32_t phase)
Reset phase to a specific value (for sync)
void set_increment(uint32_t inc)
Set the phase increment per sample.
static uint32_t freq_to_inc(float freq_hz, float sr=types::SAMPLE_RATE_F)
Convert frequency in Hz to phase increment.
uint32_t phase() const
Current phase value.
void advance(uint16_t frames, uint32_t *out)
Advance and fill a buffer with per-sample phases.
uint32_t increment() const
Current phase increment.
void advance()
Advance phase by one sample.
The numbers every layer reaches for.
Fixed-point constants and audio sample types.
constexpr float PHASE_ACCUMULATOR_RANGE
The phase accumulator's full range: uint32_t [0, 2^32) is one cycle.
Definition constants.hpp:16
Stateful, single-concern building blocks.
float SAMPLE_RATE_F
Definition fixed.hpp:17