Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions software/o_c_REV/APP_QQ.ino
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ enum ChannelSetting {
CHANNEL_SETTING_TURING_PROB_CV_SOURCE,
CHANNEL_SETTING_TURING_MODULUS_CV_SOURCE,
CHANNEL_SETTING_TURING_RANGE_CV_SOURCE,
CHANNEL_SETTING_TURING_RESET_TRIGGER,
CHANNEL_SETTING_LOGISTIC_MAP_R,
CHANNEL_SETTING_LOGISTIC_MAP_RANGE,
CHANNEL_SETTING_LOGISTIC_MAP_R_CV_SOURCE,
Expand Down Expand Up @@ -241,6 +242,10 @@ public:
return values_[CHANNEL_SETTING_TURING_RANGE_CV_SOURCE];
}

ChannelTriggerSource get_turing_reset_trigger_source() const {
return static_cast<ChannelTriggerSource>(values_[CHANNEL_SETTING_TURING_RESET_TRIGGER]);
}

uint8_t get_logistic_map_r() const {
return values_[CHANNEL_SETTING_LOGISTIC_MAP_R];
}
Expand Down Expand Up @@ -383,6 +388,7 @@ public:
last_sample_ = 0;
clock_ = 0;
int_seq_reset_ = false;
turing_reset_ = false;
continuous_offset_ = false;
schedule_mask_rotate_ = false;
prev_octave_cv_ = 0;
Expand Down Expand Up @@ -425,6 +431,11 @@ public:
ChannelTriggerSource int_seq_reset_trigger_source = get_int_seq_reset_trigger_source() ;
int_seq_reset_ = (triggers & DIGITAL_INPUT_MASK(int_seq_reset_trigger_source - 1));
}

if (source == CHANNEL_SOURCE_TURING) {
ChannelTriggerSource turing_reset_trigger_source = get_turing_reset_trigger_source();
turing_reset_ = (triggers & DIGITAL_INPUT_MASK(turing_reset_trigger_source - 1));
}

trigger_delay_.Update();
if (triggered)
Expand Down Expand Up @@ -463,6 +474,12 @@ public:
CONSTRAIN(probability, 0, 255);
}
turing_machine_.set_probability(probability);

if (turing_reset_) {
turing_machine_.reset_loop();
turing_reset_ = false;
}

if (triggered) {
uint32_t shift_register = turing_machine_.Clock();
uint8_t range = get_turing_range();
Expand Down Expand Up @@ -956,6 +973,7 @@ public:
*settings++ = CHANNEL_SETTING_TURING_MODULUS_CV_SOURCE;
*settings++ = CHANNEL_SETTING_TURING_RANGE_CV_SOURCE;
*settings++ = CHANNEL_SETTING_TURING_PROB_CV_SOURCE;
*settings++ = CHANNEL_SETTING_TURING_RESET_TRIGGER;
break;
case CHANNEL_SOURCE_LOGISTIC_MAP:
*settings++ = CHANNEL_SETTING_LOGISTIC_MAP_R;
Expand Down Expand Up @@ -1016,6 +1034,7 @@ public:
case CHANNEL_SETTING_TURING_MODULUS_CV_SOURCE:
case CHANNEL_SETTING_TURING_RANGE_CV_SOURCE:
case CHANNEL_SETTING_TURING_PROB_CV_SOURCE:
case CHANNEL_SETTING_TURING_RESET_TRIGGER:
case CHANNEL_SETTING_LOGISTIC_MAP_R:
case CHANNEL_SETTING_LOGISTIC_MAP_RANGE:
case CHANNEL_SETTING_LOGISTIC_MAP_R_CV_SOURCE:
Expand Down Expand Up @@ -1063,6 +1082,7 @@ private:
int32_t last_sample_;
uint8_t clock_;
bool int_seq_reset_;
bool turing_reset_;
int8_t continuous_offset_;
int8_t channel_index_;
int32_t schedule_mask_rotate_;
Expand Down Expand Up @@ -1131,6 +1151,7 @@ SETTINGS_DECLARE(QuantizerChannel, CHANNEL_SETTING_LAST) {
{ 0, 0, 4, "LFSR prb CV >", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 },
{ 0, 0, 4, "LFSR mod CV >", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 },
{ 0, 0, 4, "LFSR rng CV >", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 },
{ 0, 0, 4, "LFSR reset", OC::Strings::trigger_input_names_none, settings::STORAGE_TYPE_U4 },
{ 128, 1, 255, "Logistic r", NULL, settings::STORAGE_TYPE_U8 },
{ 12, 1, 120, "Logistic range", NULL, settings::STORAGE_TYPE_U8 },
{ 0, 0, 4, "Log r CV >", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 },
Expand Down
25 changes: 25 additions & 0 deletions software/o_c_REV/util/util_turing.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,15 @@ class TuringShiftRegister {
length_ = kDefaultLength;
probability_ = kDefaultProbability;
shift_register_ = 0xffffffff;
current_step_ = 0;
}

uint32_t Clock() {
uint32_t shift_register = shift_register_;

current_step_++;
if (current_step_ >= length_)
current_step_ = 0;

// Toggle LSB; there might be better random options
if (255 == probability_ ||
Expand All @@ -63,6 +68,25 @@ class TuringShiftRegister {
return shift_register & ~(0xffffffff << length_);
}

void reset_loop() {
uint8_t bits_to_shift = length_ - current_step_ - 1;

uint8_t probability_backup = probability_;

// scale down probability temporarily to avoid increased randomness when using resets
// we need to scale relative to 50% probability to keep the behavior for values over 50%
if (probability_ < 128)
probability_ = probability_ / bits_to_shift;
else if (probability_ > 128)
probability_ = 255 - (255 - probability_) / bits_to_shift;

for (uint8_t i = 0; i < bits_to_shift; i++) {
Clock();
}

probability_ = probability_backup;
}

void set_length(uint8_t length) {
// hack... don't turn all zero ...
if (length > length_)
Expand Down Expand Up @@ -92,6 +116,7 @@ class TuringShiftRegister {
uint8_t length_;
uint8_t probability_;
uint32_t shift_register_;
uint8_t current_step_;
};

}; // namespace util
Expand Down