24 static_assert(std::is_same_v<SampleType, float> || std::is_same_v<SampleType, double>);
35 if (!valid_configuration(
sample_rate, frequency_hz))
38 frequency_hz_ = frequency_hz;
46 if (!valid_configuration(sample_rate_, frequency_hz))
48 frequency_hz_ = frequency_hz;
65 if (!std::isfinite(
phase) ||
phase < SampleType{0} ||
phase >= SampleType{1})
67 phase_ =
static_cast<double>(
phase);
76 SampleType
next() noexcept {
77 const double distance = std::min(phase_, 1.0 - phase_);
78 const double x = std::numbers::pi * distance;
79 const double terms =
static_cast<double>(2 * harmonics_ + 1);
80 const double out = normalized_sinc(terms * x) / normalized_sinc(x);
82 phase_ +=
static_cast<double>(frequency_hz_) /
static_cast<double>(sample_rate_);
83 phase_ -= std::floor(phase_);
84 if (!std::isfinite(phase_))
85 phase_ = SampleType{0};
86 return std::isfinite(out) ?
static_cast<SampleType
>(out) : SampleType{0};
90 static constexpr int max_harmonics = (std::numeric_limits<int>::max() - 1) / 2;
97 const long double requested = std::floor((
static_cast<long double>(
sample_rate) * 0.5L) /
99 return std::isfinite(requested) && requested >= 1.0L &&
100 requested <= static_cast<long double>(max_harmonics);
103 static double normalized_sinc(
double x)
noexcept {
104 const double magnitude = std::fabs(x);
105 if (magnitude < 1.0e-4) {
106 const double squared =
x *
x;
107 return 1.0 - squared / 6.0 + squared * squared / 120.0;
109 return std::sin(x) /
x;
112 void update_harmonics() noexcept {
113 const long double nyquist =
static_cast<long double>(sample_rate_) * 0.5L;
114 const long double frequency =
static_cast<long double>(frequency_hz_);
115 harmonics_ =
static_cast<int>(std::floor(nyquist /
frequency));
116 if (
static_cast<long double>(harmonics_) *
frequency > nyquist)
120 SampleType sample_rate_ = SampleType{48000};
121 SampleType frequency_hz_ = SampleType{440};
Band-limited impulse train evaluated by discrete summation.
Definition blit_oscillator.hpp:22
bool set_frequency(SampleType frequency_hz) noexcept
Set the fundamental in Hz.
Definition blit_oscillator.hpp:45
double phase() const noexcept
Definition blit_oscillator.hpp:71
SampleType next() noexcept
Render the current phase and advance one sample.
Definition blit_oscillator.hpp:76
float sample_rate() const noexcept
Definition blit_oscillator.hpp:53
bool prepare(SampleType sample_rate) noexcept
Set the sample rate in Hz.
Definition blit_oscillator.hpp:28
bool prepare(SampleType sample_rate, SampleType frequency_hz) noexcept
Atomically set sample rate and fundamental.
Definition blit_oscillator.hpp:34
SampleType frequency() const noexcept
Definition blit_oscillator.hpp:56
bool reset_phase(SampleType phase=SampleType{0}) noexcept
Set normalized phase in [0, 1). Failure leaves state unchanged.
Definition blit_oscillator.hpp:64
int harmonic_count() const noexcept
Definition blit_oscillator.hpp:59
Definition additive_bank.hpp:218
BlitOscillatorT< float > BlitOscillator
Definition blit_oscillator.hpp:126
BlitOscillatorT< double > BlitOscillator64
Definition blit_oscillator.hpp:127
@ x
Definition input_events.hpp:41