Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
square_osc_bank.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <cmath>
7#include <cstddef>
8#include <vector>
9
10namespace pulp::signal {
11
35template <typename SampleType = float>
37public:
42 struct Partial {
43 SampleType frequency = SampleType{0};
44 SampleType amplitude = SampleType{1};
45 };
46
49 void prepare(SampleType sample_rate) {
50 sample_rate_ = sample_rate > SampleType{0} ? sample_rate : SampleType{44100};
51 for (auto& osc : osc_) osc.set_sample_rate(sample_rate_);
52 reset();
53 }
54
58 void set_partials(const Partial* partials, std::size_t count) {
59 using Wave = typename OscillatorT<SampleType>::Waveform;
60 osc_.resize(count);
61 amplitude_.resize(count);
62 for (std::size_t i = 0; i < count; ++i) {
63 osc_[i].set_sample_rate(sample_rate_);
64 osc_[i].set_waveform(Wave::square);
65 osc_[i].set_frequency(partials[i].frequency);
66 amplitude_[i] = partials[i].amplitude;
67 }
68 reset();
69 }
70
72 void set_partials(const std::vector<Partial>& partials) {
73 set_partials(partials.data(), partials.size());
74 }
75
76 std::size_t size() const noexcept { return osc_.size(); }
77
79 void set_frequency(std::size_t index, SampleType hz) noexcept {
80 if (index < osc_.size()) osc_[index].set_frequency(hz);
81 }
82
84 void set_amplitude(std::size_t index, SampleType amp) noexcept {
85 if (index < amplitude_.size()) amplitude_[index] = amp;
86 }
87
88 SampleType frequency(std::size_t index) const noexcept {
89 return index < osc_.size() ? osc_[index].frequency() : SampleType{0};
90 }
91
92 SampleType amplitude(std::size_t index) const noexcept {
93 return index < amplitude_.size() ? amplitude_[index] : SampleType{0};
94 }
95
97 void set_level(SampleType level) noexcept { level_ = level; }
98 SampleType level() const noexcept { return level_; }
99
102 void reset() noexcept {
103 for (auto& osc : osc_) osc.reset();
104 }
105
108 SampleType process() noexcept {
109 SampleType sum = SampleType{0};
110 const std::size_t n = osc_.size();
111 for (std::size_t i = 0; i < n; ++i) {
112 sum += amplitude_[i] * osc_[i].next();
113 }
114 return snap_to_zero(level_ * sum);
115 }
116
121 SampleType peak_bound() const noexcept {
122 SampleType s = SampleType{0};
123 for (SampleType a : amplitude_) s += std::abs(a);
124 return std::abs(level_) * s;
125 }
126
127private:
128 SampleType sample_rate_ = SampleType{44100};
129 SampleType level_ = SampleType{1};
130 std::vector<OscillatorT<SampleType>> osc_;
131 std::vector<SampleType> amplitude_;
132};
133
136
137} // namespace pulp::signal
Waveform
Definition oscillator.hpp:21
A bank of band-limited square-wave oscillators at fixed frequencies, summed into one output.
Definition square_osc_bank.hpp:36
float level() const noexcept
Definition square_osc_bank.hpp:98
void set_level(SampleType level) noexcept
Overall output gain applied after the weighted sum.
Definition square_osc_bank.hpp:97
void set_partials(const std::vector< Partial > &partials)
Convenience overload for a std::vector of partials.
Definition square_osc_bank.hpp:72
SampleType peak_bound() const noexcept
The largest magnitude process() can return with the current partials and level: |level| times the sum...
Definition square_osc_bank.hpp:121
float frequency(std::size_t index) const noexcept
Definition square_osc_bank.hpp:88
void reset() noexcept
Zero every oscillator's phase so the cluster restarts coherent.
Definition square_osc_bank.hpp:102
SampleType process() noexcept
Sum of the weighted band-limited squares for the next sample.
Definition square_osc_bank.hpp:108
void prepare(SampleType sample_rate)
Set the sample rate and re-arm the existing oscillators for it.
Definition square_osc_bank.hpp:49
std::size_t size() const noexcept
Definition square_osc_bank.hpp:76
SampleType amplitude(std::size_t index) const noexcept
Definition square_osc_bank.hpp:92
void set_frequency(std::size_t index, SampleType hz) noexcept
Retune one oscillator in place. No allocation; out-of-range is a no-op.
Definition square_osc_bank.hpp:79
void set_amplitude(std::size_t index, SampleType amp) noexcept
Reweight one oscillator in place. No allocation; out-of-range is a no-op.
Definition square_osc_bank.hpp:84
void set_partials(const Partial *partials, std::size_t count)
Install the bank's partials.
Definition square_osc_bank.hpp:58
Definition blep.hpp:72
Definition additive_bank.hpp:218
T snap_to_zero(T x)
Returns 0 if |x| < snap_threshold, else x.
Definition denormal.hpp:45
@ a
Definition formant_filter_bank.hpp:20
@ i
Definition formant_filter_bank.hpp:20
SquareOscBankT< float > SquareOscBank
Definition square_osc_bank.hpp:134
SquareOscBankT< double > SquareOscBank64
Definition square_osc_bank.hpp:135
One partial of the bank: a frequency in Hz and a linear weight.
Definition square_osc_bank.hpp:42
SampleType frequency
Definition square_osc_bank.hpp:43
SampleType amplitude
Definition square_osc_bank.hpp:44