3#include <pulp/signal/detail/modular_sequencing_common.hpp>
67template <
typename SampleType =
float>
103 sample_rate_ = sample_rate > 0.0 ? sample_rate : sample_rate_;
128 (void)register_.set_feedback_mask(feedback_mask());
133 range_v_ = seq_detail::clamp_finite(volts, 0.0,
kMaxRangeV);
142 seed_pattern_ = pattern;
159 int dac_code()
const {
return static_cast<int>(register_.state() & dac_mask()); }
160 SampleType
value()
const {
return out_; }
165 SampleType
process(
bool run_high,
bool reset_edge,
bool clock_edge,
bool data_in =
false) {
167 if (!run_high)
return out_;
168 if (!clock_edge)
return out_;
170 register_.clock(external_data_ && data_in);
176 std::uint32_t dac_mask()
const {
return (1u << dac_bits_) - 1u; }
178 std::uint32_t feedback_mask()
const {
179 return (std::uint32_t{1} << (bits_ - 1)) | (std::uint32_t{1} << tap_);
182 void clamp_config() {
183 if (dac_bits_ > bits_) dac_bits_ = bits_;
184 tap_ = std::clamp(tap_, 0, std::max(bits_ - 2, 0));
189 (void)register_.configure(bits_, feedback_mask(), seed_pattern_);
193 void refresh_output() {
194 const double levels =
static_cast<double>(dac_mask());
195 const double k =
static_cast<double>(register_.state() & dac_mask());
196 const double unit =
levels > 0.0 ? (2.0 *
k /
levels - 1.0) : 0.0;
197 out_ =
static_cast<SampleType
>(range_v_ * unit);
200 double sample_rate_ = 44100.0;
205 bool external_data_ =
false;
208 LfsrT<SampleType> register_{};
209 SampleType out_ = SampleType{0};
The Hordijk shift-register / DAC chaos sequencer.
Definition rungler.hpp:68
static constexpr int latency_samples()
Definition rungler.hpp:154
RunglerT()
Definition rungler.hpp:100
bool external_data() const
Definition rungler.hpp:139
static constexpr int kMinBits
Definition rungler.hpp:72
static constexpr int kMaxDacBits
Definition rungler.hpp:79
static constexpr int kDefaultDacBits
Definition rungler.hpp:80
static constexpr int kDefaultBits
Definition rungler.hpp:74
void set_dac_bits(int d)
Definition rungler.hpp:118
std::uint32_t register_bits() const
Current register contents, bit i at bit position i.
Definition rungler.hpp:157
static constexpr std::uint32_t kSeedPattern
Definition rungler.hpp:84
int feedback_tap() const
Definition rungler.hpp:130
int dac_bits() const
Definition rungler.hpp:123
void reset()
Definition rungler.hpp:152
void set_feedback_tap(int tap)
Definition rungler.hpp:125
SampleType value() const
Definition rungler.hpp:160
static constexpr int kMinDacBits
Definition rungler.hpp:78
void apply_reset_edge()
Verb 2 — and the one documented exception to "continuous outputs hold": the register goes back to the...
Definition rungler.hpp:150
void set_seed_pattern(std::uint32_t pattern)
Definition rungler.hpp:141
void set_external_data(bool on)
Definition rungler.hpp:138
static constexpr int kFeedbackTap
Definition rungler.hpp:88
SampleType process(bool run_high, bool reset_edge, bool clock_edge, bool data_in=false)
Advances one sample.
Definition rungler.hpp:165
static constexpr double kMaxRangeV
Definition rungler.hpp:98
int dac_code() const
Current DAC code in 0 .. 2^D − 1.
Definition rungler.hpp:159
void set_range_v(double volts)
Definition rungler.hpp:132
void prepare(double sample_rate)
Definition rungler.hpp:102
static constexpr int kMaxBits
Definition rungler.hpp:73
double range_v() const
Definition rungler.hpp:136
static constexpr double kRangeV
Definition rungler.hpp:92
std::uint32_t seed_pattern() const
Definition rungler.hpp:145
int reg_bits() const
Definition rungler.hpp:116
void set_reg_bits(int n)
Changing the register length reloads the seed pattern.
Definition rungler.hpp:111
Definition additive_bank.hpp:218
RunglerT< float > Rungler
Definition rungler.hpp:212
RunglerT< double > Rungler64
Definition rungler.hpp:213
@ levels
Definition multi_channel_meter.hpp:48
@ u
Definition formant_filter_bank.hpp:20
@ k
Definition input_events.hpp:40