33template <
typename SampleType =
float>
class LfsrT {
34 static_assert(std::is_floating_point_v<SampleType>);
45 !projection_is_finite_for(
length))
49 seed_ =
seed & register_mask();
55 if (!valid_length(
length) || !projection_is_finite_for(
length))
58 feedback_mask_ &= register_mask();
59 seed_ &= register_mask();
65 if (!mask_fits(mask, length_))
67 feedback_mask_ = mask;
72 seed_ =
seed & register_mask();
76 bool set_weight(std::size_t bit, SampleType weight)
noexcept {
77 if (bit >=
static_cast<std::size_t
>(length_) || !std::isfinite(
static_cast<double>(weight)))
79 const SampleType previous = weights_[bit];
80 weights_[bit] = weight;
81 if (!projection_is_finite()) {
82 weights_[bit] = previous;
89 weights_.fill(SampleType{});
93 if (!std::isfinite(
static_cast<double>(
offset)))
95 const SampleType previous = offset_;
97 if (!projection_is_finite()) {
108 std::uint32_t
clock(
bool external_bit =
false) noexcept {
109 const auto parity = std::popcount(state_ & feedback_mask_) & 1;
110 const auto next_bit =
static_cast<std::uint32_t
>(parity ^ (external_bit ? 1 : 0));
111 state_ = ((state_ << 1u) | next_bit) & register_mask();
116 long double output =
static_cast<long double>(offset_);
117 for (
int bit = 0; bit < length_; ++bit) {
118 if ((state_ & (std::uint32_t{1} << bit)) != 0
u)
119 output +=
static_cast<long double>(weights_[
static_cast<std::size_t
>(bit)]);
121 return static_cast<SampleType
>(output);
125 long double output =
static_cast<long double>(offset_);
126 for (
int bit = 0; bit < length_; ++bit)
127 if (weights_[
static_cast<std::size_t
>(bit)] < SampleType{})
128 output +=
static_cast<long double>(weights_[
static_cast<std::size_t
>(bit)]);
129 return static_cast<SampleType
>(output);
133 long double output =
static_cast<long double>(offset_);
134 for (
int bit = 0; bit < length_; ++bit)
135 if (weights_[
static_cast<std::size_t
>(bit)] > SampleType{})
136 output +=
static_cast<long double>(weights_[
static_cast<std::size_t
>(bit)]);
137 return static_cast<SampleType
>(output);
144 return feedback_mask_;
146 std::uint32_t
seed() const noexcept {
149 std::uint32_t
state() const noexcept {
164 static constexpr bool valid_length(
int length)
noexcept {
168 static constexpr std::uint32_t mask_for(
int length)
noexcept {
169 return length == 32 ? 0xFFFFFFFFu : ((std::uint32_t{1} <<
length) - 1u);
172 static constexpr bool mask_fits(std::uint32_t mask,
int length)
noexcept {
173 return valid_length(
length) && (mask & ~mask_for(
length)) == 0
u;
176 constexpr std::uint32_t register_mask() const noexcept {
177 return mask_for(length_);
180 bool projection_is_finite_for(
int length)
const noexcept {
181 long double minimum =
static_cast<long double>(offset_);
183 for (
int bit = 0; bit <
length; ++bit) {
184 const long double weight =
185 static_cast<long double>(weights_[
static_cast<std::size_t
>(bit)]);
191 const long double limit =
static_cast<long double>(std::numeric_limits<SampleType>::max());
195 bool projection_is_finite() const noexcept {
196 return projection_is_finite_for(length_);
199 std::array<SampleType, kMaxLength> weights_{};
200 SampleType offset_{};
Configurable Fibonacci linear-feedback shift register with a weighted register-to-output projection.
Definition lfsr.hpp:33
bool set_feedback_mask(std::uint32_t mask) noexcept
Definition lfsr.hpp:64
static constexpr int tail_samples() noexcept
Definition lfsr.hpp:159
bool set_offset(SampleType offset) noexcept
Definition lfsr.hpp:92
bool set_weight(std::size_t bit, SampleType weight) noexcept
Definition lfsr.hpp:76
bool configure(int length, std::uint32_t feedback_mask, std::uint32_t seed) noexcept
Definition lfsr.hpp:43
SampleType maximum_output() const noexcept
Definition lfsr.hpp:132
SampleType minimum_output() const noexcept
Definition lfsr.hpp:124
int length() const noexcept
Definition lfsr.hpp:140
static constexpr std::uint32_t kDefaultFeedbackMask
Definition lfsr.hpp:40
SampleType weighted_output() const noexcept
Definition lfsr.hpp:115
static constexpr int kMinLength
Definition lfsr.hpp:37
static constexpr std::uint32_t kDefaultSeed
Definition lfsr.hpp:41
std::uint32_t clock(bool external_bit=false) noexcept
Definition lfsr.hpp:108
std::uint32_t seed() const noexcept
Definition lfsr.hpp:146
bool set_length(int length) noexcept
Definition lfsr.hpp:54
float offset() const noexcept
Definition lfsr.hpp:152
void clear_weights() noexcept
Definition lfsr.hpp:88
static constexpr int kDefaultLength
Definition lfsr.hpp:39
static constexpr int kMaxLength
Definition lfsr.hpp:38
void set_seed(std::uint32_t seed) noexcept
Definition lfsr.hpp:71
void reset() noexcept
Definition lfsr.hpp:104
static constexpr int latency_samples() noexcept
Definition lfsr.hpp:156
std::uint32_t state() const noexcept
Definition lfsr.hpp:149
std::uint32_t feedback_mask() const noexcept
Definition lfsr.hpp:143
Definition additive_bank.hpp:218
LfsrT< float > Lfsr
Definition lfsr.hpp:207
@ maximum
Definition spectrum_trace.hpp:34
@ u
Definition formant_filter_bank.hpp:20
LfsrT< double > Lfsr64
Definition lfsr.hpp:208
float minimum(const float *data, std::size_t count) noexcept