50 frequency_ = freq_hz / sr;
58 void set_note(
float midi_note,
float sample_rate = 48000.0f) {
67 pw_ = (pw < 0.05f) ? 0.05f : (pw > 0.95f) ? 0.95f : pw;
78 void process(
float* out, uint16_t frames) {
80 while (pos < frames) {
81 uint16_t n = frames - pos;
82 if (n > MAX_BLOCK) n = MAX_BLOCK;
83 render_float(out + pos, n);
84 if (amplitude_ != 1.0f) {
85 for (uint16_t i = 0; i < n; ++i) {
86 out[pos + i] *= amplitude_;
108 return static_cast<uint32_t
>(phase_ * 4294967296.0f);
115 static constexpr uint16_t MAX_BLOCK = 48;
118 float frequency_ = 0.0f;
120 float next_sample_ = 0.0f;
123 float amplitude_ = 1.0f;
128 void render_float(
float* out, uint16_t frames) {
140 void render_saw_f(
float* out, uint16_t frames) {
141 using namespace dsp::polyblep;
142 float phase = phase_;
143 float next = next_sample_;
144 float freq = frequency_;
146 for (uint16_t i = 0; i < frames; ++i) {
147 float this_sample = next;
153 float t =
phase / freq;
154 this_sample -= this_blep(t);
155 next -= next_blep(t);
158 this_sample = 2.0f * this_sample - 1.0f;
160 out[i] = clamp(this_sample);
169 void render_square_f(
float* out, uint16_t frames,
float pw) {
170 using namespace dsp::polyblep;
171 float phase = phase_;
172 float next = next_sample_;
173 float freq = frequency_;
178 for (uint16_t i = 0; i < frames; ++i) {
179 float this_sample = next;
185 if (high &&
phase >= fall_at) {
186 float t = (
phase - fall_at) / freq;
194 float t =
phase / freq;
200 next += high ? 1.0f : 0.0f;
201 this_sample = 2.0f * this_sample - 1.0f;
203 out[i] = clamp(this_sample);
213 void render_triangle_f(
float* out, uint16_t frames) {
214 using namespace dsp::polyblep;
215 float phase = phase_;
216 float next = next_sample_;
217 float freq = frequency_;
220 constexpr float slope_up = 2.0f;
221 constexpr float slope_down = 2.0f;
222 const float discontinuity = (slope_up + slope_down) * freq;
224 for (uint16_t i = 0; i < frames; ++i) {
225 float this_sample = next;
231 if (high ^ (
phase < 0.5f)) {
232 float t = (
phase - 0.5f) / freq;
240 float t =
phase / freq;
249 : 1.0f - (
phase - 0.5f) * slope_down;
251 out[i] = clamp(2.0f * this_sample - 1.0f);
261 static float clamp(
float s) {
262 return (s > 1.0f) ? 1.0f : (s < -1.0f) ? -1.0f : s;