diff --git a/software/o_c_REV/APP_AUTOMATONNETZ.ino b/software/o_c_REV/APP_AUTOMATONNETZ.ino index 4e675028..fef385db 100644 --- a/software/o_c_REV/APP_AUTOMATONNETZ.ino +++ b/software/o_c_REV/APP_AUTOMATONNETZ.ino @@ -63,6 +63,7 @@ #include "tonnetz/tonnetz_state.h" #include "OC_bitmaps.h" #include "OC_menus.h" +#include "OC_trigger_delays.h" #define FRACTIONAL_BITS 24 #define CLOCK_STEP_RES (0x1 << FRACTIONAL_BITS) @@ -195,8 +196,8 @@ public: quantizer.Init(); tonnetz_state.init(); - trigger_delay_.Init(); - delayed_triggers_ = 0; + trigger_delays_.Init(); + strum_inhibit_ = false; memset(&ui, 0, sizeof(ui)); ui.cell_cursor.Init(CELL_SETTING_TRANSFORM, CELL_SETTING_LAST - 1); @@ -262,14 +263,6 @@ public: return static_cast(values_[GRID_SETTING_CLEARMODE]); } - void set_delayed_triggers(uint32_t delayed_triggers) { - delayed_triggers_ = delayed_triggers; - } - - uint32_t get_delayed_triggers() { - return(delayed_triggers_); - } - // End of settings void ISR(); @@ -312,8 +305,8 @@ private: int cell_transpose_, cell_inversion_; uint32_t history_; - util::TriggerDelay trigger_delay_; - uint32_t delayed_triggers_; + OC::TriggerDelays trigger_delays_; + bool strum_inhibit_ ; util::RingBuffer user_actions_; util::CriticalSection critical_section_; @@ -368,15 +361,7 @@ void FASTRUN AutomatonnetzState::ISR() { update_trigger_out(); uint32_t triggers = OC::DigitalInputs::clocked(); - - trigger_delay_.Update(); - if (triggers) { - trigger_delay_.Push(OC::trigger_delay_ticks[get_trigger_delay()]); - set_delayed_triggers(triggers) ; - triggers = 0; - } - if (trigger_delay_.triggered()) - triggers = get_delayed_triggers(); + triggers = trigger_delays_.Process(triggers, OC::trigger_delay_ticks[get_trigger_delay()]); bool reset = false; while (user_actions_.readable()) { @@ -432,15 +417,18 @@ void FASTRUN AutomatonnetzState::ISR() { // Arp/strum if (chord_changed && OUTPUTA_MODE_STRUM == output_mode()) { arp_index_ = 0; + strum_inhibit_ = false; } else if ((triggers & TRIGGER_MASK_ARP) && !reset && !OC::DigitalInputs::read_immediate()) { ++arp_index_; - if (arp_index_ >= 3) + if (arp_index_ >= 3) { arp_index_ = 0; + strum_inhibit_ = true; + } } - if (triggers & TRIGGER_MASK_GRID) + if ((triggers & TRIGGER_MASK_GRID) || (triggers & TRIGGER_MASK_ARP)) update_outputs(chord_changed, cell_transpose_, cell_inversion_); } @@ -477,8 +465,10 @@ void AutomatonnetzState::update_outputs(bool chord_changed, int transpose, int i } break; case OUTPUTA_MODE_ARP: - case OUTPUTA_MODE_STRUM: OC::DAC::set_voltage_scaled_semitone(tonnetz_state.outputs(arp_index_ + 1), octave(), OC::DAC::get_voltage_scaling(DAC_CHANNEL_A)); + case OUTPUTA_MODE_STRUM: + if (!strum_inhibit_) + OC::DAC::set_voltage_scaled_semitone(tonnetz_state.outputs(arp_index_ + 1), octave(), OC::DAC::get_voltage_scaling(DAC_CHANNEL_A)); break; case OUTPUTA_MODE_LAST: default: diff --git a/software/o_c_REV/APP_A_SEQ.ino b/software/o_c_REV/APP_A_SEQ.ino index 2823079f..daa37d63 100644 --- a/software/o_c_REV/APP_A_SEQ.ino +++ b/software/o_c_REV/APP_A_SEQ.ino @@ -36,12 +36,14 @@ #include "braids_quantizer_scales.h" #include "extern/dspinst.h" #include "util/util_arp.h" +#include "peaks_multistage_envelope.h" + namespace menu = OC::menu; const uint8_t NUM_CHANNELS = 2; -const uint8_t MULT_MAX = 18; // max multiplier -const uint8_t MULT_BY_ONE = 11; // default multiplication +const uint8_t MULT_MAX = 26; // max multiplier +const uint8_t MULT_BY_ONE = 19; // default multiplication const uint8_t PULSEW_MAX = 255; // max pulse width [ms] const uint32_t SCALE_PULSEWIDTH = 58982; // 0.9 for signed_multiply_32x16b @@ -90,11 +92,18 @@ const uint64_t pw_scale_[] = { }; // = 2^32 * divisor / 64 const uint8_t divisors_[] = { - + 65, 64, + 63, + 49, 48, + 47, + 33, 32, + 31, + 17, 16, + 15, 8, 7, 6, @@ -145,9 +154,27 @@ enum SEQ_ChannelSetting { SEQ_CHANNEL_SETTING_SEQUENCE_ARP_DIRECTION_CV_SOURCE, SEQ_CHANNEL_SETTING_SEQUENCE_ARP_RANGE_CV_SOURCE, SEQ_CHANNEL_SETTING_DIRECTION_CV_SOURCE, - SEQ_CHANNEL_SETTING_BROWNIAN_CV, - SEQ_CHANNEL_SETTING_LENGTH_CV, + SEQ_CHANNEL_SETTING_BROWNIAN_CV_SOURCE, + SEQ_CHANNEL_SETTING_LENGTH_CV_SOURCE, + SEQ_CHANNEL_SETTING_ENV_ATTACK_CV_SOURCE, + SEQ_CHANNEL_SETTING_ENV_DECAY_CV_SOURCE, + SEQ_CHANNEL_SETTING_ENV_SUSTAIN_CV_SOURCE, + SEQ_CHANNEL_SETTING_ENV_RELEASE_CV_SOURCE, + SEQ_CHANNEL_SETTING_ENV_LOOPS_CV_SOURCE, SEQ_CHANNEL_SETTING_DUMMY, + // aux envelope settings + SEQ_CHANNEL_SETTING_ENV_ATTACK_DURATION, + SEQ_CHANNEL_SETTING_ENV_ATTACK_SHAPE, + SEQ_CHANNEL_SETTING_ENV_DECAY_DURATION, + SEQ_CHANNEL_SETTING_ENV_DECAY_SHAPE, + SEQ_CHANNEL_SETTING_ENV_SUSTAIN_LEVEL, + SEQ_CHANNEL_SETTING_ENV_RELEASE_DURATION, + SEQ_CHANNEL_SETTING_ENV_RELEASE_SHAPE, + SEQ_CHANNEL_SETTING_ENV_MAX_LOOPS, + SEQ_CHANNEL_SETTING_ENV_ATTACK_RESET_BEHAVIOUR, + SEQ_CHANNEL_SETTING_ENV_ATTACK_FALLING_GATE_BEHAVIOUR, + SEQ_CHANNEL_SETTING_ENV_DECAY_RELEASE_RESET_BEHAVIOUR, + // marker SEQ_CHANNEL_SETTING_LAST }; @@ -219,6 +246,9 @@ enum SEQ_DIRECTIONS { enum SQ_AUX_MODES { GATE, COPY, + ENV_AD, + ENV_ADR, + ENV_ADSR, SQ_AUX_MODES_LAST }; @@ -380,7 +410,7 @@ public: } uint8_t get_sequence_length_cv_source() const { - return values_[SEQ_CHANNEL_SETTING_LENGTH_CV]; + return values_[SEQ_CHANNEL_SETTING_LENGTH_CV_SOURCE]; } uint8_t get_mult_cv_source() const { @@ -424,9 +454,73 @@ public: } int8_t get_brownian_probability_cv() const { - return values_[SEQ_CHANNEL_SETTING_BROWNIAN_CV]; + return values_[SEQ_CHANNEL_SETTING_BROWNIAN_CV_SOURCE]; } - + + uint16_t get_attack_duration() const { + return SCALE8_16(values_[SEQ_CHANNEL_SETTING_ENV_ATTACK_DURATION]); + } + + int8_t get_attack_duration_cv() const { + return values_[SEQ_CHANNEL_SETTING_ENV_ATTACK_CV_SOURCE]; + } + + peaks::EnvelopeShape get_attack_shape() const { + return static_cast(values_[SEQ_CHANNEL_SETTING_ENV_ATTACK_SHAPE]); + } + + uint16_t get_decay_duration() const { + return SCALE8_16(values_[SEQ_CHANNEL_SETTING_ENV_DECAY_DURATION]); + } + + int8_t get_decay_duration_cv() const { + return values_[SEQ_CHANNEL_SETTING_ENV_DECAY_CV_SOURCE]; + } + + peaks::EnvelopeShape get_decay_shape() const { + return static_cast(values_[SEQ_CHANNEL_SETTING_ENV_DECAY_SHAPE]); + } + + uint16_t get_sustain_level() const { + return SCALE8_16(values_[SEQ_CHANNEL_SETTING_ENV_SUSTAIN_LEVEL]); + } + + int8_t get_sustain_level_cv() const { + return values_[SEQ_CHANNEL_SETTING_ENV_SUSTAIN_CV_SOURCE]; + } + + uint16_t get_release_duration() const { + return SCALE8_16(values_[SEQ_CHANNEL_SETTING_ENV_RELEASE_DURATION]); + } + + int8_t get_release_duration_cv() const { + return values_[SEQ_CHANNEL_SETTING_ENV_RELEASE_CV_SOURCE]; + } + + peaks::EnvelopeShape get_release_shape() const { + return static_cast(values_[SEQ_CHANNEL_SETTING_ENV_RELEASE_SHAPE]); + } + + peaks::EnvResetBehaviour get_attack_reset_behaviour() const { + return static_cast(values_[SEQ_CHANNEL_SETTING_ENV_ATTACK_RESET_BEHAVIOUR]); + } + + peaks::EnvFallingGateBehaviour get_attack_falling_gate_behaviour() const { + return static_cast(values_[SEQ_CHANNEL_SETTING_ENV_ATTACK_FALLING_GATE_BEHAVIOUR]); + } + + peaks::EnvResetBehaviour get_decay_release_reset_behaviour() const { + return static_cast(values_[SEQ_CHANNEL_SETTING_ENV_DECAY_RELEASE_RESET_BEHAVIOUR]); + } + + uint16_t get_max_loops() const { + return values_[SEQ_CHANNEL_SETTING_ENV_MAX_LOOPS] << 9 ; + } + + uint8_t get_env_loops_cv_source() const { + return values_[SEQ_CHANNEL_SETTING_ENV_LOOPS_CV_SOURCE]; + } + void update_pattern_mask(uint16_t mask, uint8_t sequence) { switch(sequence) { @@ -597,8 +691,13 @@ public: apply_value(SEQ_CHANNEL_SETTING_DIRECTION_CV_SOURCE, 0); apply_value(SEQ_CHANNEL_SETTING_SEQUENCE_ARP_DIRECTION_CV_SOURCE, 0); apply_value(SEQ_CHANNEL_SETTING_SEQUENCE_ARP_RANGE_CV_SOURCE, 0); - apply_value(SEQ_CHANNEL_SETTING_BROWNIAN_CV, 0); - apply_value(SEQ_CHANNEL_SETTING_LENGTH_CV, 0); + apply_value(SEQ_CHANNEL_SETTING_BROWNIAN_CV_SOURCE, 0); + apply_value(SEQ_CHANNEL_SETTING_LENGTH_CV_SOURCE, 0); + apply_value(SEQ_CHANNEL_SETTING_ENV_ATTACK_CV_SOURCE, 0); + apply_value(SEQ_CHANNEL_SETTING_ENV_DECAY_CV_SOURCE, 0); + apply_value(SEQ_CHANNEL_SETTING_ENV_SUSTAIN_CV_SOURCE, 0); + apply_value(SEQ_CHANNEL_SETTING_ENV_RELEASE_CV_SOURCE, 0); + apply_value(SEQ_CHANNEL_SETTING_ENV_LOOPS_CV_SOURCE, 0); } int get_scale(uint8_t dummy) const { @@ -657,6 +756,7 @@ public: apply_value(SEQ_CHANNEL_SETTING_CLOCK, trigger_source); quantizer_.Init(); input_map_.Init(); + env_.Init(); force_update_ = true; force_scale_update_ = true; gate_state_ = step_state_ = OFF; @@ -674,6 +774,9 @@ public: prev_playmode_ = get_playmode(); pending_sync_ = false; sequence_change_pending_ = 0x0; + prev_gate_raised_ = 0 ; + env_gate_raised_ = 0 ; + env_gate_state_ = 0 ; ext_frequency_in_ticks_ = 0xFFFFFFFF; channel_frequency_in_ticks_ = 0xFFFFFFFF; @@ -979,6 +1082,47 @@ public: // update output: step_pitch_ = quantizer_.Process(step_pitch_, 0, _transpose); + int32_t _attack = get_attack_duration(); + int32_t _decay = get_decay_duration(); + int32_t _sustain = get_sustain_level(); + int32_t _release = get_release_duration(); + int32_t _loops = get_max_loops(); + + switch (_aux_mode) { + case ENV_AD: + case ENV_ADR: + case ENV_ADSR: + if (get_attack_duration_cv()) { + _attack += OC::ADC::value(static_cast(get_attack_duration_cv() - 1)) << 3; + USAT16(_attack) ; + } + if (get_decay_duration_cv()) { + _decay += OC::ADC::value(static_cast(get_decay_duration_cv() - 1)) << 3; + USAT16(_decay); + } + if (get_sustain_level_cv()) { + _sustain += OC::ADC::value(static_cast(get_sustain_level_cv() - 1)) << 4; + CONSTRAIN(_sustain, 0, 65534); + } + if (get_release_duration_cv()) { + _release += OC::ADC::value(static_cast(get_release_duration_cv() - 1)) << 3; + USAT16(_release) ; + } + if (get_env_loops_cv_source()) { + _loops += OC::ADC::value(static_cast(get_env_loops_cv_source() - 1)) ; + CONSTRAIN(_loops,1<<8, 65534) ; + } + // set the specified reset behaviours + env_.set_attack_reset_behaviour(get_attack_reset_behaviour()); + env_.set_attack_falling_gate_behaviour(get_attack_falling_gate_behaviour()); + env_.set_decay_release_reset_behaviour(get_decay_release_reset_behaviour()); + // set number of loops + env_.set_max_loops(_loops); + break; + default: + break; + } + switch (_aux_mode) { case COPY: @@ -995,6 +1139,29 @@ public: step_pitch_aux_ = quantizer_.Process(step_pitch_aux_, 0, _transpose); } break; + case ENV_AD: + { + env_.set_ad(_attack, _decay, 0, 2); + env_.set_attack_shape(get_attack_shape()); + env_.set_decay_shape(get_decay_shape()); + } + break; + case ENV_ADR: + { + env_.set_adr(_attack, _decay, _sustain >> 1, _release, 0, 2); + env_.set_attack_shape(get_attack_shape()); + env_.set_decay_shape(get_decay_shape()); + env_.set_release_shape(get_release_shape()); + } + break; + case ENV_ADSR: + { + env_.set_adsr(_attack, _decay, _sustain >> 1, _release); + env_.set_attack_shape(get_attack_shape()); + env_.set_decay_shape(get_decay_shape()); + env_.set_release_shape(get_release_shape()); + } + break; default: break; } @@ -1007,7 +1174,7 @@ public: * below: pulsewidth stuff */ - if (!_aux_mode && gate_state_) { + if (_aux_mode != COPY && gate_state_) { // pulsewidth setting -- int16_t _pulsewidth = get_pulsewidth(); @@ -1127,12 +1294,13 @@ public: sequence_length = get_sequence_length(_num_seq) + sequence_length_cv; CONSTRAIN(sequence_length, OC::Patterns::kMin, OC::Patterns::kMax); - if (active_sequence_ != _num_seq || sequence_length != active_sequence_length_) + if (active_sequence_ != _num_seq || sequence_length != active_sequence_length_ || prev_playmode_ != _playmode) arpeggiator_.UpdateArpeggiator(channel_id_, _num_seq, get_mask(_num_seq), sequence_length); active_sequence_ = _num_seq; active_sequence_length_ = sequence_length; if (_reset) arpeggiator_.reset(); + prev_playmode_ = _playmode; // and skip the stuff below: _playmode = 0xFF; break; @@ -1170,6 +1338,7 @@ public: case PM_TR3: { sequence_max = _playmode - PM_SEQ3; + prev_playmode_ = _playmode; // trigger? uint8_t _advance_trig = (channel_id_ == DAC_CHANNEL_A) ? digitalReadFast(TR2) : digitalReadFast(TR4); @@ -1492,14 +1661,42 @@ public: // aux output: *settings++ = SEQ_CHANNEL_SETTING_MODE; - switch (get_aux_mode()) { - - case 0: + switch (get_aux_mode()) { + case GATE: *settings++ = SEQ_CHANNEL_SETTING_PULSEWIDTH; break; - case 1: + case COPY: *settings++ = SEQ_CHANNEL_SETTING_OCTAVE_AUX; break; + case ENV_AD: + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_DURATION; + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_SHAPE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_DECAY_DURATION; + *settings++ = SEQ_CHANNEL_SETTING_ENV_DECAY_SHAPE; + *settings++ = SEQ_CHANNEL_SETTING_PULSEWIDTH; + *settings++ = SEQ_CHANNEL_SETTING_ENV_MAX_LOOPS; + break; + case ENV_ADR: + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_DURATION; + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_SHAPE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_DECAY_DURATION; + *settings++ = SEQ_CHANNEL_SETTING_ENV_DECAY_SHAPE; + *settings++ = SEQ_CHANNEL_SETTING_PULSEWIDTH; + *settings++ = SEQ_CHANNEL_SETTING_ENV_SUSTAIN_LEVEL; + *settings++ = SEQ_CHANNEL_SETTING_ENV_RELEASE_DURATION; + *settings++ = SEQ_CHANNEL_SETTING_ENV_RELEASE_SHAPE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_MAX_LOOPS; + break; + case ENV_ADSR: + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_DURATION; + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_SHAPE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_DECAY_DURATION; + *settings++ = SEQ_CHANNEL_SETTING_ENV_DECAY_SHAPE; + *settings++ = SEQ_CHANNEL_SETTING_PULSEWIDTH; + *settings++ = SEQ_CHANNEL_SETTING_ENV_SUSTAIN_LEVEL; + *settings++ = SEQ_CHANNEL_SETTING_ENV_RELEASE_DURATION; + *settings++ = SEQ_CHANNEL_SETTING_ENV_RELEASE_SHAPE; + break; default: break; } @@ -1535,7 +1732,7 @@ public: break; } - *settings++ = SEQ_CHANNEL_SETTING_LENGTH_CV; // = playmode + *settings++ = SEQ_CHANNEL_SETTING_LENGTH_CV_SOURCE; // = playmode if (get_playmode() < PM_SH1) { @@ -1546,7 +1743,7 @@ public: else *settings++ = SEQ_CHANNEL_SETTING_DIRECTION_CV_SOURCE; // = directions if (get_playmode() != PM_ARP && get_direction() == BROWNIAN) - *settings++ = SEQ_CHANNEL_SETTING_BROWNIAN_CV; + *settings++ = SEQ_CHANNEL_SETTING_BROWNIAN_CV_SOURCE; *settings++ = SEQ_CHANNEL_SETTING_MULT_CV_SOURCE; @@ -1559,12 +1756,31 @@ public: switch (get_aux_mode()) { - case 0: + case GATE: *settings++ = SEQ_CHANNEL_SETTING_PULSEWIDTH_CV_SOURCE; break; - case 1: + case COPY: *settings++ = SEQ_CHANNEL_SETTING_OCTAVE_AUX_CV_SOURCE; break; + case ENV_AD: + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_CV_SOURCE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_DECAY_CV_SOURCE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_LOOPS_CV_SOURCE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_RESET_BEHAVIOUR; + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_FALLING_GATE_BEHAVIOUR; + *settings++ = SEQ_CHANNEL_SETTING_ENV_DECAY_RELEASE_RESET_BEHAVIOUR; + break; + case ENV_ADR: + case ENV_ADSR: + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_CV_SOURCE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_DECAY_CV_SOURCE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_SUSTAIN_CV_SOURCE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_RELEASE_CV_SOURCE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_LOOPS_CV_SOURCE; + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_RESET_BEHAVIOUR; + *settings++ = SEQ_CHANNEL_SETTING_ENV_ATTACK_FALLING_GATE_BEHAVIOUR; + *settings++ = SEQ_CHANNEL_SETTING_ENV_DECAY_RELEASE_RESET_BEHAVIOUR; + break; default: break; } @@ -1573,6 +1789,12 @@ public: *settings++ = SEQ_CHANNEL_SETTING_TRIGGER_DELAY; // *settings++ = SEQ_CHANNEL_SETTING_CLOCK; // = reset source } + + *settings++ = SEQ_CHANNEL_SETTING_DUMMY; // = mode + *settings++ = SEQ_CHANNEL_SETTING_DUMMY; // = mode + *settings++ = SEQ_CHANNEL_SETTING_DUMMY; // = mode + *settings++ = SEQ_CHANNEL_SETTING_DUMMY; // = mode + } break; default: @@ -1594,19 +1816,34 @@ public: int8_t _mode = get_aux_mode(); uint32_t _output = 0; - + switch (_mode) { - case 0: // gate + case GATE: // gate #ifdef BUCHLA_4U _output = (get_step_gate() == ON) ? OC::DAC::get_octave_offset(dacChannel, OCTAVES - OC::DAC::kOctaveZero - 0x2) : OC::DAC::get_zero_offset(dacChannel); #else _output = (get_step_gate() == ON) ? OC::DAC::get_octave_offset(dacChannel, OCTAVES - OC::DAC::kOctaveZero - 0x1) : OC::DAC::get_zero_offset(dacChannel); #endif break; - case 1: // copy + case COPY: // copy _output = OC::DAC::pitch_to_scaled_voltage_dac(dacChannel, get_step_pitch_aux(), 0, OC::DAC::get_voltage_scaling(dacChannel)); break; + // code to process envelopes here + case ENV_AD: + case ENV_ADR: + case ENV_ADSR: + env_gate_state_ = 0; + env_gate_raised_ = (get_step_gate() == ON); + if (env_gate_raised_ && !prev_gate_raised_) + env_gate_state_ |= peaks::CONTROL_GATE_RISING; + if (env_gate_raised_) + env_gate_state_ |= peaks::CONTROL_GATE; + else if (prev_gate_raised_) + env_gate_state_ |= peaks::CONTROL_GATE_FALLING; + prev_gate_raised_ = env_gate_raised_; + _output = OC::DAC::get_zero_offset(dacChannel) + env_.ProcessSingleSample(env_gate_state_); + break; default: break; } @@ -1638,6 +1875,9 @@ private: uint32_t channel_frequency_in_ticks_; uint32_t pulse_width_in_ticks_; uint16_t gate_state_; + uint8_t prev_gate_raised_; + uint8_t env_gate_state_; + uint8_t env_gate_raised_; uint16_t step_state_; int32_t step_pitch_; int32_t step_pitch_aux_; @@ -1666,6 +1906,8 @@ private: braids::Quantizer quantizer_; OC::Input_Map input_map_; OC::DigitalInputDisplay clock_display_; + peaks::MultistageEnvelope env_; + }; const char* const SEQ_CHANNEL_TRIGGER_sources[] = { @@ -1677,11 +1919,11 @@ const char* const reset_trigger_sources[] = { }; const char* const display_multipliers[] = { - "/64", "/48", "/32", "/16", "/8", "/7", "/6", "/5", "/4", "/3", "/2", "-", "x2", "x3", "x4", "x5", "x6", "x7", "x8" + "/65", "/64", "/63", "/49", "/48", "/47", "/33", "/32", "/31", "/17", "/16", "/15", "/8", "/7", "/6", "/5", "/4", "/3", "/2", "-", "x2", "x3", "x4", "x5", "x6", "x7", "x8" }; const char* const modes[] = { - "gate", "copy" + "gate", "copy", "AD", "ADR", "ADSR", }; const char* const cv_ranges[] = { @@ -1698,7 +1940,7 @@ const char* const arp_range[] = { SETTINGS_DECLARE(SEQ_Channel, SEQ_CHANNEL_SETTING_LAST) { - { 0, 0, 1, "aux. mode", modes, settings::STORAGE_TYPE_U4 }, + { 0, 0, 4, "aux. mode", modes, settings::STORAGE_TYPE_U4 }, { SEQ_CHANNEL_TRIGGER_TR1, 0, SEQ_CHANNEL_TRIGGER_NONE, "clock src", SEQ_CHANNEL_TRIGGER_sources, settings::STORAGE_TYPE_U4 }, { 0, 0, OC::kNumDelayTimes - 1, "trigger delay", OC::Strings::trigger_delay_times, settings::STORAGE_TYPE_U8 }, { 2, 0, SEQ_CHANNEL_TRIGGER_LAST - 1, "reset/mute", reset_trigger_sources, settings::STORAGE_TYPE_U8 }, @@ -1738,7 +1980,24 @@ SETTINGS_DECLARE(SEQ_Channel, SEQ_CHANNEL_SETTING_LAST) { { 0, 0, 4, "direction ->", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 }, { 0, 0, 4, "-->brwn.prb ->", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 }, { 0, 0, 4, "seq.length ->", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 }, - { 0, 0, 1, "-", NULL, settings::STORAGE_TYPE_U4 } // DUMMY, use to store update behaviour + { 0, 0, 4, "att dur ->", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 }, + { 0, 0, 4, "dec dur ->", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 }, + { 0, 0, 4, "sus lvl ->", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 }, + { 0, 0, 4, "rel dur ->", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U4 }, + { 0, 0, 4, "env loops ->", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U8 }, + { 0, 0, 1, "-", NULL, settings::STORAGE_TYPE_U4 }, // DUMMY, use to store update behaviour + // envelope parameters + { 128, 0, 255, "--> att dur", NULL, settings::STORAGE_TYPE_U8 }, + { peaks::ENV_SHAPE_QUARTIC, peaks::ENV_SHAPE_LINEAR, peaks::ENV_SHAPE_LAST - 1, "--> att shape", OC::Strings::envelope_shapes, settings::STORAGE_TYPE_U16 }, + { 128, 0, 255, "--> dec dur", NULL, settings::STORAGE_TYPE_U8 }, + { peaks::ENV_SHAPE_EXPONENTIAL, peaks::ENV_SHAPE_LINEAR, peaks::ENV_SHAPE_LAST - 1, "--> dec shape", OC::Strings::envelope_shapes, settings::STORAGE_TYPE_U16 }, + { 128, 0, 255, "--> sus lvl", NULL, settings::STORAGE_TYPE_U16 }, + { 128, 0, 255, "--> rel dur", NULL, settings::STORAGE_TYPE_U8 }, + { peaks::ENV_SHAPE_EXPONENTIAL, peaks::ENV_SHAPE_LINEAR, peaks::ENV_SHAPE_LAST - 1, "--> rel shape", OC::Strings::envelope_shapes, settings::STORAGE_TYPE_U16 }, + {1, 1, 127, "--> loops", NULL, settings::STORAGE_TYPE_U8 }, + { peaks::RESET_BEHAVIOUR_NULL, peaks::RESET_BEHAVIOUR_NULL, peaks::RESET_BEHAVIOUR_LAST - 1, "att reset", OC::Strings::reset_behaviours, settings::STORAGE_TYPE_U8 }, + { peaks::FALLING_GATE_BEHAVIOUR_IGNORE, peaks::FALLING_GATE_BEHAVIOUR_IGNORE, peaks::FALLING_GATE_BEHAVIOUR_LAST - 1, "att fall gt", OC::Strings::falling_gate_behaviours, settings::STORAGE_TYPE_U8 }, + { peaks::RESET_BEHAVIOUR_SEGMENT_PHASE, peaks::RESET_BEHAVIOUR_NULL, peaks::RESET_BEHAVIOUR_LAST - 1, "dec/rel reset", OC::Strings::reset_behaviours, settings::STORAGE_TYPE_U8 }, }; class SEQ_State { @@ -2176,7 +2435,11 @@ void SEQ_menu() { } break; case SEQ_CHANNEL_SETTING_PULSEWIDTH: - list_item.Draw_PW_Value(value, attr); + if (channel.get_aux_mode() < ENV_AD) { + list_item.Draw_PW_Value(value, attr); + } else { + list_item.Draw_PW_Value_Char(value, attr, "--> sus dur"); + } break; case SEQ_CHANNEL_SETTING_DUMMY: list_item.DrawNoValue(value, attr); diff --git a/software/o_c_REV/APP_BBGEN.ino b/software/o_c_REV/APP_BBGEN.ino index 1c485bfd..bdd668cc 100644 --- a/software/o_c_REV/APP_BBGEN.ino +++ b/software/o_c_REV/APP_BBGEN.ino @@ -215,7 +215,7 @@ SETTINGS_DECLARE(BouncingBall, BB_SETTING_LAST) { { BB_CV_MAPPING_NONE, BB_CV_MAPPING_NONE, BB_CV_MAPPING_LAST - 1, "CV2 -> ", bb_cv_mapping_names, settings::STORAGE_TYPE_U4 }, { BB_CV_MAPPING_NONE, BB_CV_MAPPING_NONE, BB_CV_MAPPING_LAST - 1, "CV3 -> ", bb_cv_mapping_names, settings::STORAGE_TYPE_U4 }, { BB_CV_MAPPING_NONE, BB_CV_MAPPING_NONE, BB_CV_MAPPING_LAST - 1, "CV4 -> ", bb_cv_mapping_names, settings::STORAGE_TYPE_U4 }, - { 0, 0, 1, "Hard reset", OC::Strings::no_yes, settings::STORAGE_TYPE_U4 }, + { 0, 0, 1, "Hard reset", OC::Strings::no_yes, settings::STORAGE_TYPE_U8 }, }; class QuadBouncingBalls { diff --git a/software/o_c_REV/APP_BYTEBEATGEN.ino b/software/o_c_REV/APP_BYTEBEATGEN.ino index cecab59f..782cd588 100644 --- a/software/o_c_REV/APP_BYTEBEATGEN.ino +++ b/software/o_c_REV/APP_BYTEBEATGEN.ino @@ -360,7 +360,7 @@ SETTINGS_DECLARE(ByteBeat, BYTEBEAT_SETTING_LAST) { { 126, 0, 255, "Parameter 0", NULL, settings::STORAGE_TYPE_U8 }, { 126, 0, 255, "Parameter 1", NULL, settings::STORAGE_TYPE_U8 }, { 127, 0, 255, "Parameter 2", NULL, settings::STORAGE_TYPE_U8 }, - { 0, 0, 1, "Loop mode", OC::Strings::no_yes, settings::STORAGE_TYPE_U4 }, + { 0, 0, 1, "Loop mode", OC::Strings::no_yes, settings::STORAGE_TYPE_U8 }, { 0, 0, 255, "Loop begin ++", NULL, settings::STORAGE_TYPE_U8 }, { 0, 0, 255, "Loop begin +", NULL, settings::STORAGE_TYPE_U8 }, { 0, 0, 255, "Loop begin", NULL, settings::STORAGE_TYPE_U8 }, diff --git a/software/o_c_REV/APP_CHORDS.ino b/software/o_c_REV/APP_CHORDS.ino index 976448df..382c553e 100644 --- a/software/o_c_REV/APP_CHORDS.ino +++ b/software/o_c_REV/APP_CHORDS.ino @@ -996,7 +996,7 @@ SETTINGS_DECLARE(Chords, CHORDS_SETTING_LAST) { { 0, 0, 11, "root", OC::Strings::note_names_unpadded, settings::STORAGE_TYPE_U8 }, { 0, 0, OC::Chords::NUM_CHORD_PROGRESSIONS - 1, "progression", chords_slots, settings::STORAGE_TYPE_U8 }, { 65535, 1, 65535, "scale -->", NULL, settings::STORAGE_TYPE_U16 }, // mask - { 0, 0, CHORDS_CV_SOURCE_LAST - 1, "CV source", chords_cv_main_source, settings::STORAGE_TYPE_U4 }, /// to do .. + { 0, 0, CHORDS_CV_SOURCE_LAST - 1, "CV source", chords_cv_main_source, settings::STORAGE_TYPE_U8 }, /// to do .. { CHORDS_ADVANCE_TRIGGER_SOURCE_TR2, 0, CHORDS_ADVANCE_TRIGGER_SOURCE_LAST - 1, "chords trg src", chords_advance_trigger_sources, settings::STORAGE_TYPE_U8 }, { 0, 0, CHORDS_PLAYMODES_LAST - 1, "playmode", chord_playmodes, settings::STORAGE_TYPE_U8 }, { 0, 0, CHORDS_DIRECTIONS_LAST - 1, "direction", OC::Strings::seq_directions, settings::STORAGE_TYPE_U8 }, diff --git a/software/o_c_REV/APP_DQ.ino b/software/o_c_REV/APP_DQ.ino index 816358a9..02410079 100644 --- a/software/o_c_REV/APP_DQ.ino +++ b/software/o_c_REV/APP_DQ.ino @@ -1085,7 +1085,7 @@ SETTINGS_DECLARE(DQ_QuantizerChannel, DQ_CHANNEL_SETTING_LAST) { { 0, 0, 11, "root #2", OC::Strings::note_names_unpadded, settings::STORAGE_TYPE_U8 }, { 0, 0, 11, "root #3", OC::Strings::note_names_unpadded, settings::STORAGE_TYPE_U8 }, { 0, 0, 11, "root #4", OC::Strings::note_names_unpadded, settings::STORAGE_TYPE_U8 }, - { 0, 0, NUM_SCALE_SLOTS - 1, "scale #", dq_seq_scales, settings::STORAGE_TYPE_U4 }, + { 0, 0, NUM_SCALE_SLOTS - 1, "scale #", dq_seq_scales, settings::STORAGE_TYPE_U8 }, { 65535, 1, 65535, "--> edit", NULL, settings::STORAGE_TYPE_U16 }, { 65535, 1, 65535, "--> edit", NULL, settings::STORAGE_TYPE_U16 }, { 65535, 1, 65535, "--> edit", NULL, settings::STORAGE_TYPE_U16 }, diff --git a/software/o_c_REV/APP_ENVGEN.ino b/software/o_c_REV/APP_ENVGEN.ino index 4bafeb23..084fc664 100644 --- a/software/o_c_REV/APP_ENVGEN.ino +++ b/software/o_c_REV/APP_ENVGEN.ino @@ -694,10 +694,6 @@ const char* const segment_names[] = { "Attack", "Decay", "Sustain/Level", "Release" }; -const char* const envelope_shapes[peaks::ENV_SHAPE_LAST] = { - "Lin", "Exp", "Quart", "Sine", "Ledge", "Cliff", "Gate", "BgDip", "MeDip", "LtDip", "Wiggl" -}; - const char* const cv_mapping_names[CV_MAPPING_LAST] = { "None", "Att", "Dec", "Sus", "Rel", "ADR", "Eleng", "Efill", "Eoffs", "Delay", "Ampl", "Loops" }; @@ -706,14 +702,6 @@ const char* const trigger_delay_modes[TRIGGER_DELAY_LAST] = { "Off", "Queue", "Ring" }; -const char* const reset_behaviours[peaks::RESET_BEHAVIOUR_LAST] = { - "None", "SP", "SLP", "SL", "P", -}; - -const char* const falling_gate_behaviours[peaks::FALLING_GATE_BEHAVIOUR_LAST] = { - "Ignor", "Honor", -}; - const char* const euclidean_lengths[] = { "Off", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", " 10", " 11", " 12", " 13", " 14", " 15", " 16", " 17", " 18", " 19", " 20", @@ -749,13 +737,13 @@ SETTINGS_DECLARE(EnvelopeGenerator, ENV_SETTING_LAST) { { CV_MAPPING_NONE, CV_MAPPING_NONE, CV_MAPPING_LAST - 1, "CV2 -> ", cv_mapping_names, settings::STORAGE_TYPE_U4 }, { CV_MAPPING_NONE, CV_MAPPING_NONE, CV_MAPPING_LAST - 1, "CV3 -> ", cv_mapping_names, settings::STORAGE_TYPE_U4 }, { CV_MAPPING_NONE, CV_MAPPING_NONE, CV_MAPPING_LAST - 1, "CV4 -> ", cv_mapping_names, settings::STORAGE_TYPE_U4 }, - { peaks::RESET_BEHAVIOUR_NULL, peaks::RESET_BEHAVIOUR_NULL, peaks::RESET_BEHAVIOUR_LAST - 1, "Attack reset", reset_behaviours, settings::STORAGE_TYPE_U4 }, - { peaks::FALLING_GATE_BEHAVIOUR_IGNORE, peaks::FALLING_GATE_BEHAVIOUR_IGNORE, peaks::FALLING_GATE_BEHAVIOUR_LAST - 1, "Att fall gt", falling_gate_behaviours, settings::STORAGE_TYPE_U8 }, - { peaks::RESET_BEHAVIOUR_SEGMENT_PHASE, peaks::RESET_BEHAVIOUR_NULL, peaks::RESET_BEHAVIOUR_LAST - 1, "DecRel reset", reset_behaviours, settings::STORAGE_TYPE_U4 }, + { peaks::RESET_BEHAVIOUR_NULL, peaks::RESET_BEHAVIOUR_NULL, peaks::RESET_BEHAVIOUR_LAST - 1, "Attack reset", OC::Strings::reset_behaviours, settings::STORAGE_TYPE_U4 }, + { peaks::FALLING_GATE_BEHAVIOUR_IGNORE, peaks::FALLING_GATE_BEHAVIOUR_IGNORE, peaks::FALLING_GATE_BEHAVIOUR_LAST - 1, "Att fall gt", OC::Strings::falling_gate_behaviours, settings::STORAGE_TYPE_U8 }, + { peaks::RESET_BEHAVIOUR_SEGMENT_PHASE, peaks::RESET_BEHAVIOUR_NULL, peaks::RESET_BEHAVIOUR_LAST - 1, "DecRel reset", OC::Strings::reset_behaviours, settings::STORAGE_TYPE_U4 }, { 0, 0, 1, "Gate high", OC::Strings::no_yes, settings::STORAGE_TYPE_U4 }, - { peaks::ENV_SHAPE_QUARTIC, peaks::ENV_SHAPE_LINEAR, peaks::ENV_SHAPE_LAST - 1, "Attack shape", envelope_shapes, settings::STORAGE_TYPE_U4 }, - { peaks::ENV_SHAPE_EXPONENTIAL, peaks::ENV_SHAPE_LINEAR, peaks::ENV_SHAPE_LAST - 1, "Decay shape", envelope_shapes, settings::STORAGE_TYPE_U4 }, - { peaks::ENV_SHAPE_EXPONENTIAL, peaks::ENV_SHAPE_LINEAR, peaks::ENV_SHAPE_LAST - 1, "Release shape", envelope_shapes, settings::STORAGE_TYPE_U4 }, + { peaks::ENV_SHAPE_QUARTIC, peaks::ENV_SHAPE_LINEAR, peaks::ENV_SHAPE_LAST - 1, "Attack shape", OC::Strings::envelope_shapes, settings::STORAGE_TYPE_U4 }, + { peaks::ENV_SHAPE_EXPONENTIAL, peaks::ENV_SHAPE_LINEAR, peaks::ENV_SHAPE_LAST - 1, "Decay shape", OC::Strings::envelope_shapes, settings::STORAGE_TYPE_U4 }, + { peaks::ENV_SHAPE_EXPONENTIAL, peaks::ENV_SHAPE_LINEAR, peaks::ENV_SHAPE_LAST - 1, "Release shape", OC::Strings::envelope_shapes, settings::STORAGE_TYPE_U4 }, { 0, 0, 13, "Attack mult", time_multipliers, settings::STORAGE_TYPE_U4 }, { 0, 0, 13, "Decay mult", time_multipliers, settings::STORAGE_TYPE_U4 }, {0, 0, 13, "Release mult", time_multipliers, settings::STORAGE_TYPE_U4 }, diff --git a/software/o_c_REV/APP_H1200.ino b/software/o_c_REV/APP_H1200.ino index 2175c1a2..b9efb3c1 100644 --- a/software/o_c_REV/APP_H1200.ino +++ b/software/o_c_REV/APP_H1200.ino @@ -25,6 +25,7 @@ #include "OC_bitmaps.h" #include "OC_strings.h" +#include "OC_trigger_delays.h" #include "tonnetz/tonnetz_state.h" #include "util/util_settings.h" #include "util/util_ringbuffer.h" @@ -77,8 +78,8 @@ enum H1200Setting { H1200_SETTING_NSH_TRANSFORM_PRIO_CV, H1200_SETTING_CV_SAMPLING, H1200_SETTING_OUTPUT_MODE, - H1200_SETTING_TRIGGER_TYPE, H1200_SETTING_TRIGGER_DELAY, + H1200_SETTING_TRIGGER_TYPE, H1200_SETTING_EUCLIDEAN_CV1_MAPPING, H1200_SETTING_EUCLIDEAN_CV2_MAPPING, H1200_SETTING_EUCLIDEAN_CV3_MAPPING, @@ -331,8 +332,8 @@ public: *settings++ = H1200_SETTING_NSH_TRANSFORM_PRIO_CV; *settings++ = H1200_SETTING_CV_SAMPLING; *settings++ = H1200_SETTING_OUTPUT_MODE; - *settings++ = H1200_SETTING_TRIGGER_TYPE; *settings++ = H1200_SETTING_TRIGGER_DELAY; + *settings++ = H1200_SETTING_TRIGGER_TYPE; switch (get_trigger_type()) { case H1200_TRIGGER_TYPE_EUCLIDEAN: @@ -436,8 +437,8 @@ SETTINGS_DECLARE(H1200Settings, H1200_SETTING_LAST) { {H1200_CV_SOURCE_NONE, H1200_CV_SOURCE_NONE, H1200_CV_SOURCE_LAST-1, "NSH Prior CV", OC::Strings::cv_input_names_none, settings::STORAGE_TYPE_U8}, {H1200_CV_SAMPLING_CONT, H1200_CV_SAMPLING_CONT, H1200_CV_SAMPLING_LAST-1, "CV sampling", h1200_cv_sampling, settings::STORAGE_TYPE_U8}, {OUTPUT_CHORD_VOICING, 0, OUTPUT_MODE_LAST-1, "Output mode", output_mode_names, settings::STORAGE_TYPE_U8}, - {H1200_TRIGGER_TYPE_PLR, 0, H1200_TRIGGER_TYPE_LAST-1, "Trigger type", trigger_type_names, settings::STORAGE_TYPE_U8}, { 0, 0, OC::kNumDelayTimes - 1, "Trigger delay", OC::Strings::trigger_delay_times, settings::STORAGE_TYPE_U8 }, + {H1200_TRIGGER_TYPE_PLR, 0, H1200_TRIGGER_TYPE_LAST-1, "Trigger type", trigger_type_names, settings::STORAGE_TYPE_U8}, {H1200_EUCL_CV_MAPPING_NONE, H1200_EUCL_CV_MAPPING_NONE, H1200_EUCL_CV_MAPPING_LAST-1, "Eucl CV1 map", h1200_eucl_cv_mappings, settings::STORAGE_TYPE_U8}, {H1200_EUCL_CV_MAPPING_NONE, H1200_EUCL_CV_MAPPING_NONE, H1200_EUCL_CV_MAPPING_LAST-1, "Eucl CV2 map", h1200_eucl_cv_mappings, settings::STORAGE_TYPE_U8}, {H1200_EUCL_CV_MAPPING_NONE, H1200_EUCL_CV_MAPPING_NONE, H1200_EUCL_CV_MAPPING_LAST-1, "Eucl CV3 map", h1200_eucl_cv_mappings, settings::STORAGE_TYPE_U8}, @@ -493,8 +494,7 @@ public: quantizer.Init(); tonnetz_state.init(); - trigger_delay_.Init(); - delayed_triggers_ = 0; + trigger_delays_.Init(); euclidean_counter_ = 0; root_sample_ = false; @@ -607,14 +607,6 @@ public: ui_actions.Write(H1200::ACTION_MANUAL_RESET); } - void set_delayed_triggers(uint32_t delayed_triggers) { - delayed_triggers_ = delayed_triggers; - } - - uint32_t get_delayed_triggers() { - return(delayed_triggers_); - } - void Render(int32_t root, int inversion, int octave, OutputMode output_mode) { tonnetz_state.render(root + octave * 12, inversion); @@ -648,8 +640,7 @@ public: OC::SemitoneQuantizer quantizer; TonnetzState tonnetz_state; util::RingBuffer ui_actions; - util::TriggerDelay trigger_delay_; - uint32_t delayed_triggers_; + OC::TriggerDelays trigger_delays_; uint32_t euclidean_counter_; bool root_sample_ ; int32_t root_ ; @@ -678,14 +669,7 @@ H1200State h1200_state; void FASTRUN H1200_clock(uint32_t triggers) { - h1200_state.trigger_delay_.Update(); - if (triggers) { - h1200_state.trigger_delay_.Push(OC::trigger_delay_ticks[h1200_settings.get_trigger_delay()]); - h1200_state.set_delayed_triggers(triggers) ; - triggers = 0; - } - if (h1200_state.trigger_delay_.triggered()) - triggers = h1200_state.get_delayed_triggers(); + triggers = h1200_state.trigger_delays_.Process(triggers, OC::trigger_delay_ticks[h1200_settings.get_trigger_delay()]); // Reset has priority if (triggers & TRIGGER_MASK_TR1) { diff --git a/software/o_c_REV/APP_QQ.ino b/software/o_c_REV/APP_QQ.ino index e379c515..1b14cb9b 100644 --- a/software/o_c_REV/APP_QQ.ino +++ b/software/o_c_REV/APP_QQ.ino @@ -1111,7 +1111,7 @@ SETTINGS_DECLARE(QuantizerChannel, CHANNEL_SETTING_LAST) { { QQ_DEST_NONE, QQ_DEST_NONE, QQ_DEST_LAST - 1, "CV aux >", aux_cv_dest, settings::STORAGE_TYPE_U8 }, { CHANNEL_TRIGGER_CONTINUOUS_DOWN, 0, CHANNEL_TRIGGER_LAST - 1, "Trigger source", OC::Strings::channel_trigger_sources, settings::STORAGE_TYPE_U8 }, { 1, 1, 16, "Clock div", NULL, settings::STORAGE_TYPE_U8 }, - { 0, 0, OC::kNumDelayTimes - 1, "Trigger delay", OC::Strings::trigger_delay_times, settings::STORAGE_TYPE_U4 }, + { 0, 0, OC::kNumDelayTimes - 1, "Trigger delay", OC::Strings::trigger_delay_times, settings::STORAGE_TYPE_U8 }, { 0, -5, 7, "Transpose", NULL, settings::STORAGE_TYPE_I8 }, { 0, -4, 4, "Octave", NULL, settings::STORAGE_TYPE_I8 }, { 0, -999, 999, "Fine", NULL, settings::STORAGE_TYPE_I16 }, diff --git a/software/o_c_REV/APP_REFS.ino b/software/o_c_REV/APP_REFS.ino index 38f852ef..e800eeed 100644 --- a/software/o_c_REV/APP_REFS.ino +++ b/software/o_c_REV/APP_REFS.ino @@ -38,6 +38,13 @@ // static constexpr double kAaboveMidCtoC0 = 0.03716272234383494188492; +// +#ifdef FLIP_180 +const uint8_t DAC_CHANNEL_FTM = DAC_CHANNEL_A; +#else +const uint8_t DAC_CHANNEL_FTM = DAC_CHANNEL_D; +#endif + // #ifdef BUCHLA_4U const float target_multipliers[OCTAVES] = { 1.0f, 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f, 128.0f, 256.0f, 512.0f }; @@ -526,7 +533,7 @@ public: *settings++ = REF_SETTING_AUTOTUNE; //*settings++ = REF_SETTING_AUTOTUNE_ERROR; - if (DAC_CHANNEL_D == dac_channel_) { + if (DAC_CHANNEL_FTM == dac_channel_) { *settings++ = REF_SETTING_NOTES_OR_BPM; *settings++ = REF_SETTING_A_ABOVE_MID_C_INTEGER; *settings++ = REF_SETTING_A_ABOVE_MID_C_MANTISSA; @@ -600,7 +607,7 @@ SETTINGS_DECLARE(ReferenceChannel, REF_SETTING_LAST) { { 0, 0, 99, " > mantissa", nullptr, settings::STORAGE_TYPE_U8 }, { CHANNEL_PPQN_4, CHANNEL_PPQN_1, CHANNEL_PPQN_LAST - 1, "> ppqn", ppqn_labels, settings::STORAGE_TYPE_U8 }, { 0, 0, 0, "--> autotune", NULL, settings::STORAGE_TYPE_U8 }, - { 0, 0, 0, "-", NULL, settings::STORAGE_TYPE_U4 } // dummy + { 0, 0, 0, "-", NULL, settings::STORAGE_TYPE_U8 } // dummy }; class ReferencesApp { @@ -614,8 +621,8 @@ public: for (auto &channel : channels_) channel.Init(static_cast(dac_channel++)); - ui.selected_channel = DAC_CHANNEL_D; - ui.cursor.Init(0, channels_[DAC_CHANNEL_D].num_enabled_settings() - 1); + ui.selected_channel = DAC_CHANNEL_FTM; + ui.cursor.Init(0, channels_[DAC_CHANNEL_FTM].num_enabled_settings() - 1); freq_sum_ = 0; freq_count_ = 0; @@ -669,7 +676,7 @@ public: float get_ppqn() { float ppqn_ = 4.0 ; - switch(channels_[DAC_CHANNEL_D].get_channel_ppqn()){ + switch(channels_[DAC_CHANNEL_FTM].get_channel_ppqn()){ case CHANNEL_PPQN_1: ppqn_ = 1.0; break; @@ -712,11 +719,11 @@ public: } bool get_notes_or_bpm( ) { - return(static_cast(channels_[DAC_CHANNEL_D].get_notes_or_bpm())) ; + return(static_cast(channels_[DAC_CHANNEL_FTM].get_notes_or_bpm())) ; } float get_C0_freq() { - return(static_cast(channels_[DAC_CHANNEL_D].get_a_above_mid_c() * kAaboveMidCtoC0)); + return(static_cast(channels_[DAC_CHANNEL_FTM].get_a_above_mid_c() * kAaboveMidCtoC0)); } private: @@ -918,7 +925,11 @@ void REFS_screensaver() { int32_t freq_decicents_residual_ = ((freq_decicents_deviation_ - ((freq_octave_ - 1) * 12000)) % 1000) - 500; if (frequency_ > 0.0) { - graphics.printf("TR4 %7.3f Hz", frequency_) ; + #ifdef FLIP_180 + graphics.printf("TR1 %7.3f Hz", frequency_); + #else + graphics.printf("TR4 %7.3f Hz", frequency_); + #endif graphics.setPrintPos(2, 56); if (references_app.get_notes_or_bpm()) { graphics.printf("%7.2f bpm %2.0fppqn", bpm_, references_app.get_ppqn()); @@ -961,10 +972,19 @@ void REFS_handleEncoderEvent(const UI::Event &event) { } if (OC::CONTROL_ENCODER_L == event.control) { + + int previous = references_app.selected_channel().num_enabled_settings(); int selected = references_app.ui.selected_channel + event.value; CONSTRAIN(selected, 0, NUM_REF_CHANNELS - 0x1); references_app.ui.selected_channel = selected; - references_app.ui.cursor.AdjustEnd(references_app.selected_channel().num_enabled_settings() - 1); + + // hack -- deal w/ menu items / channels + if ((references_app.ui.cursor.cursor_pos() > 4) && (previous > references_app.selected_channel().num_enabled_settings())) { + references_app.ui.cursor.Init(0, 0); + references_app.ui.cursor.AdjustEnd(references_app.selected_channel().num_enabled_settings() - 1); + } + else + references_app.ui.cursor.AdjustEnd(references_app.selected_channel().num_enabled_settings() - 1); } else if (OC::CONTROL_ENCODER_R == event.control) { if (references_app.ui.cursor.editing()) { auto &selected_channel = references_app.selected_channel(); diff --git a/software/o_c_REV/OC_DAC.cpp b/software/o_c_REV/OC_DAC.cpp index f1576dd3..6f922b3c 100644 --- a/software/o_c_REV/OC_DAC.cpp +++ b/software/o_c_REV/OC_DAC.cpp @@ -36,6 +36,7 @@ #include #include "OC_DAC.h" #include "OC_gpio.h" +#include "OC_options.h" #include "OC_calibration.h" #include "OC_autotune_presets.h" #include "OC_autotune.h" @@ -207,8 +208,11 @@ uint8_t DAC::DAC_scaling[DAC_CHANNEL_LAST]; void set8565_CHA(uint32_t data) { uint32_t _data = OC::DAC::MAX_VALUE - data; - + #ifdef FLIP_180 + SPIFIFO.write(0b00010110, SPI_CONTINUE); + #else SPIFIFO.write(0b00010000, SPI_CONTINUE); + #endif SPIFIFO.write16(_data); SPIFIFO.read(); SPIFIFO.read(); @@ -217,7 +221,11 @@ void set8565_CHA(uint32_t data) { void set8565_CHB(uint32_t data) { uint32_t _data = OC::DAC::MAX_VALUE - data; + #ifdef FLIP_180 + SPIFIFO.write(0b00010100, SPI_CONTINUE); + #else SPIFIFO.write(0b00010010, SPI_CONTINUE); + #endif SPIFIFO.write16(_data); SPIFIFO.read(); SPIFIFO.read(); @@ -226,7 +234,11 @@ void set8565_CHB(uint32_t data) { void set8565_CHC(uint32_t data) { uint32_t _data = OC::DAC::MAX_VALUE - data; + #ifdef FLIP_180 + SPIFIFO.write(0b00010010, SPI_CONTINUE); + #else SPIFIFO.write(0b00010100, SPI_CONTINUE); + #endif SPIFIFO.write16(_data); SPIFIFO.read(); SPIFIFO.read(); @@ -235,7 +247,11 @@ void set8565_CHC(uint32_t data) { void set8565_CHD(uint32_t data) { uint32_t _data = OC::DAC::MAX_VALUE - data; + #ifdef FLIP_180 + SPIFIFO.write(0b00010000, SPI_CONTINUE); + #else SPIFIFO.write(0b00010110, SPI_CONTINUE); + #endif SPIFIFO.write16(_data); SPIFIFO.read(); SPIFIFO.read(); diff --git a/software/o_c_REV/OC_digital_inputs.cpp b/software/o_c_REV/OC_digital_inputs.cpp index 52751a90..c48cbc2b 100644 --- a/software/o_c_REV/OC_digital_inputs.cpp +++ b/software/o_c_REV/OC_digital_inputs.cpp @@ -2,6 +2,7 @@ #include #include "OC_digital_inputs.h" #include "OC_gpio.h" +#include "OC_options.h" /*static*/ uint32_t OC::DigitalInputs::clocked_mask_; @@ -65,9 +66,14 @@ void OC::DigitalInputs::Init() { } void OC::DigitalInputs::reInit() { - // re init TR4, to avoid conflict with the FTM - pinMode(TR4, OC_GPIO_TRx_PINMODE); - attachInterrupt(TR4, tr4_ISR, FALLING); + // re-init TR4, to avoid conflict with the FTM + #ifdef FLIP_180 + pinMode(TR1, OC_GPIO_TRx_PINMODE); + attachInterrupt(TR1, tr1_ISR, FALLING); + #else + pinMode(TR4, OC_GPIO_TRx_PINMODE); + attachInterrupt(TR4, tr4_ISR, FALLING); + #endif } /*static*/ diff --git a/software/o_c_REV/OC_gpio.h b/software/o_c_REV/OC_gpio.h index 25561525..21cd5fc9 100644 --- a/software/o_c_REV/OC_gpio.h +++ b/software/o_c_REV/OC_gpio.h @@ -1,18 +1,35 @@ #ifndef OC_GPIO_H_ #define OC_GPIO_H_ -#define CV1 19 -#define CV2 18 -#define CV3 20 -#define CV4 17 +#include "OC_options.h" -#define TR1 0 -#define TR2 1 -#define TR3 2 -#define TR4 3 - -#define but_top 5 -#define but_bot 4 +#ifdef FLIP_180 + #define CV4 19 + #define CV3 18 + #define CV2 20 + #define CV1 17 + + #define TR4 0 + #define TR3 1 + #define TR2 2 + #define TR1 3 + + #define but_top 4 + #define but_bot 5 +#else + #define CV1 19 + #define CV2 18 + #define CV3 20 + #define CV4 17 + + #define TR1 0 + #define TR2 1 + #define TR3 2 + #define TR4 3 + + #define but_top 5 + #define but_bot 4 +#endif #define OLED_DC 6 #define OLED_RST 7 @@ -26,13 +43,23 @@ #define DAC_CS 10 // NOTE: encoder pins R1/R2 changed for rev >= 2c -#define encR1 16 -#define encR2 15 -#define butR 14 - -#define encL1 22 -#define encL2 21 -#define butL 23 +#ifdef FLIP_180 + #define encL1 16 + #define encL2 15 + #define butL 14 + + #define encR1 22 + #define encR2 21 + #define butR 23 +#else + #define encR1 16 + #define encR2 15 + #define butR 14 + + #define encL1 22 + #define encL2 21 + #define butL 23 +#endif // NOTE: back side :( #define OC_GPIO_DEBUG_PIN1 24 diff --git a/software/o_c_REV/OC_menus.h b/software/o_c_REV/OC_menus.h index c77e76fd..aca73023 100644 --- a/software/o_c_REV/OC_menus.h +++ b/software/o_c_REV/OC_menus.h @@ -310,6 +310,11 @@ struct SettingsListItem { graphics.print(attr.name); } + inline void DrawCharName(const char* name_string) const { + graphics.setPrintPos(x + kIndentDx, y + kTextDy); + graphics.print(name_string); + } + inline void DrawDefault(int value, const settings::value_attr &attr) const { DrawName(attr); @@ -324,6 +329,28 @@ struct SettingsListItem { if (selected) graphics.invertRect(x, y, kDisplayWidth - x, kMenuLineH - 1); } + + inline void Draw_PW_Value_Char(int value, const settings::value_attr &attr, const char* name_string) const { + DrawCharName(name_string); + + graphics.setPrintPos(endx, y + kTextDy); + + if(attr.value_names) + graphics.print_right(attr.value_names[value]); + else { + if (value == 0x0) // echo + graphics.print_right("echo"); + else if (value == 0xFF) // 50% + graphics.print_right("50%"); + else + graphics.pretty_print_right(value); + } + + if (editing) + menu::DrawEditIcon(valuex, y, value, attr); + if (selected) + graphics.invertRect(x, y, kDisplayWidth - x, kMenuLineH - 1); + } inline void Draw_PW_Value(int value, const settings::value_attr &attr) const { DrawName(attr); diff --git a/software/o_c_REV/OC_options.h b/software/o_c_REV/OC_options.h index 269731e5..2712f08e 100644 --- a/software/o_c_REV/OC_options.h +++ b/software/o_c_REV/OC_options.h @@ -15,5 +15,6 @@ //#define BORING_APP_NAMES /* ------------ print debug messages to USB serial -------------------------------------------------- */ //#define PRINT_DEBUG - +/* ------------ flip screen / IO mapping ------------------------------------------------------------ */ +//#define FLIP_180 #endif diff --git a/software/o_c_REV/OC_scales.cpp b/software/o_c_REV/OC_scales.cpp index 88658cdc..cafcad72 100644 --- a/software/o_c_REV/OC_scales.cpp +++ b/software/o_c_REV/OC_scales.cpp @@ -53,30 +53,30 @@ const char* const scale_names_short[] = { "E /4", "EA/4", "BHAI", - "GUNA", + // "GUNA", "MARW", - "SHRI", - "PURV", - "BILA", + // "SHRI", + // "PURV", + // "BILA", "YAMA", - "KAFI", + // "KAFI", "BHIM", - "DARB", - "RAGE", - "KHAM", - "MIMA", - "PARA", - "RANG", - "GANG", - "KAME", - "PAKA", - "NATB", - "KAUN", + // "DARB", + // "RAGE", + // "KHAM", + // "MIMA", + // "PARA", + // "RANG", + // "GANG", + // "KAME", + // "PAKA", + // "NATB", + // "KAUN", "BAIR", - "BTOD", - "CHAN", - "KTOD", - "JOGE", + // "BTOD", + // "CHAN", + // "KTOD", + // "JOGE", "VALL", "1322", "MANF", @@ -150,16 +150,16 @@ const char* const scale_names_short[] = { "B-Pe", "B-Pj", "B-Pl", - "16H3", - "14H3", - "12H3", - "10H3", - "8H3", - "16S3", - "14S3", - "12S3", - "10S3", - "8S3" +// "16H3", +// "14H3", +// "12H3", +// "10H3", +// "8H3", +// "16S3", +// "14S3", +// "12S3", +// "10S3", +// "8S3" }; const char* const scale_names[] = { @@ -192,30 +192,30 @@ const char* const scale_names[] = { "E /4", "EA/4", "Bhairav", - "Gunakri", + // "Gunakri", "Marwa", - "Shree [Camel]", - "Purvi", - "Bilawal", + // "Shree [Camel]", + // "Purvi", + // "Bilawal", "Yaman", - "Kafi", + // "Kafi", "Bhimpalasree", - "Darbari", - "Rageshree", - "Khamaj", - "Mimal", - "Parameshwari", - "Rangeshwari", - "Gangeshwari", - "Kameshwari", - "Pa Khafi", - "Natbhairav", - "Malkauns", + // "Darbari", + // "Rageshree", + // "Khamaj", + // "Mimal", + // "Parameshwari", + // "Rangeshwari", + // "Gangeshwari", + // "Kameshwari", + // "Pa Khafi", + // "Natbhairav", + // "Malkauns", "Bairagi", - "B Todi", - "Chandradeep", - "Kaushik Todi", - "Jogeshwari", + // "B Todi", + // "Chandradeep", + // "Kaushik Todi", + // "Jogeshwari", "Tart.-Vallotti", "13of22tETgen=5", @@ -289,16 +289,16 @@ const char* const scale_names[] = { "Bohlen-Pierce =", "Bohlen-Pierce j", "Bohlen-Pierce l", - "8-24-HD3[16]", - "7-21-HD3[14]", - "6-18-HD3[12]", - "5-15-HD3[10]", - "4-12-HD3[8]", - "24-8-SD3[16]", - "21-7-SD3[14]", - "18-6-SD3[12]", - "15-5-SD3[10]", - "12-4-SD3[8]" +// "8-24-HD3[16]", +// "7-21-HD3[14]", +// "6-18-HD3[12]", +// "5-15-HD3[10]", +// "4-12-HD3[8]", +// "24-8-SD3[16]", +// "21-7-SD3[14]", +// "18-6-SD3[12]", +// "15-5-SD3[10]", +// "12-4-SD3[8]" }; const char* const voltage_scalings[] = { diff --git a/software/o_c_REV/OC_strings.cpp b/software/o_c_REV/OC_strings.cpp index 24584878..e96f2c7b 100644 --- a/software/o_c_REV/OC_strings.cpp +++ b/software/o_c_REV/OC_strings.cpp @@ -42,9 +42,13 @@ namespace OC { "hope", "love", "life", "age", "clysm", "monk", "NERV", "Trurl", "Pirx", "Snaut", "Hari" , "Kris", "Tichy", "Bregg", "Avon", "Orac" }; + const char* const envelope_shapes[11] = { + "Lin", "Exp", "Quart", "Sine", "Ledge", "Cliff", "Gate", "BgDip", "MeDip", "LtDip", "Wiggl" + }; + const char* const integer_sequence_names[] = { "pi", "vnEck", "ssdn", "Dress", "PNinf" , "Dsum", "Dsum4", "Dsum5", "CDn2", "Frcti" - }; + }; const char* const integer_sequence_dirs[] = { "swing", "loop" @@ -63,6 +67,13 @@ namespace OC { "-", "rng", "len", "prb" }; + const char* const reset_behaviours[] = { + "None", "SP", "SLP", "SL", "P", + }; + + const char* const falling_gate_behaviours[] = { + "Ignor", "Honor", + }; const uint8_t pi_digits[kIntSeqLen] = {3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5,0,2,8,8,4,1,9,7,1,6,9,3,9,9,3,7,5,1,0,5,8,2,0,9,7,4,9,4,4,5,9,2, diff --git a/software/o_c_REV/OC_strings.h b/software/o_c_REV/OC_strings.h index 845493c0..d69a7d9d 100644 --- a/software/o_c_REV/OC_strings.h +++ b/software/o_c_REV/OC_strings.h @@ -26,12 +26,15 @@ namespace OC { extern const char * const scaling_string[]; extern const char * const encoder_config_strings[]; extern const char * const bytebeat_equation_names[]; + extern const char * const envelope_shapes[]; extern const char * const integer_sequence_names[]; extern const char * const integer_sequence_dirs[]; extern const char * const trigger_delay_times[kNumDelayTimes]; extern const char* const chord_property_names[]; extern const char* const mult[]; extern const char* const TM_aux_cv_destinations[]; + extern const char* const reset_behaviours[]; + extern const char* const falling_gate_behaviours[]; // Not strings but are constant integer sequences extern const uint8_t pi_digits[kIntSeqLen]; // extern const uint8_t phi_digits[kIntSeqLen]; diff --git a/software/o_c_REV/OC_trigger_delays.h b/software/o_c_REV/OC_trigger_delays.h new file mode 100644 index 00000000..b1e47f1f --- /dev/null +++ b/software/o_c_REV/OC_trigger_delays.h @@ -0,0 +1,66 @@ +// Copyright (c) 2017 Patrick Dowling +// +// Author: Patrick Dowling (pld@gurkenkiste.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#ifndef OC_TRIGGER_DELAYS_H_ +#define OC_TRIGGER_DELAYS_H_ + +#include "OC_digital_inputs.h" +#include "util/util_trigger_delay.h" + +namespace OC { + +template +class TriggerDelays { +public: + TriggerDelays() { } + ~TriggerDelays() { } + + void Init() { + for (auto &d : delays_) + d.Init(); + } + + uint32_t Process(uint32_t trigger_mask, uint32_t delay_ticks) { + uint32_t triggered = 0; + uint32_t mask = 0x1; + for (auto &d : delays_) { + d.Update(); + if (trigger_mask & mask) + d.Push(delay_ticks); + if (d.triggered()) + triggered |= mask; + mask <<= 1; + } + return triggered; + } + +protected: + + util::TriggerDelay delays_[DIGITAL_INPUT_LAST]; + +}; + +}; // namespace OC + +#endif // OC_TRIGGER_DELAYS_H_ + diff --git a/software/o_c_REV/OC_version.h b/software/o_c_REV/OC_version.h index 4b1f9bda..19cfc844 100644 --- a/software/o_c_REV/OC_version.h +++ b/software/o_c_REV/OC_version.h @@ -3,5 +3,5 @@ // // GENERATED FILE, DO NOT EDIT // -#define OC_VERSION "v1.3.2" +#define OC_VERSION "v1.3.3" #endif diff --git a/software/o_c_REV/braids_quantizer_scales.h b/software/o_c_REV/braids_quantizer_scales.h index acc3bfd6..42bff10d 100644 --- a/software/o_c_REV/braids_quantizer_scales.h +++ b/software/o_c_REV/braids_quantizer_scales.h @@ -85,53 +85,53 @@ const Scale scales[] = { // bhairav (From yarns source code) { 12 << 7, 7, { 0, 115, 494, 637, 899, 1014, 1393} }, // gunakri (From yarns source code) - { 12 << 7, 5, { 0, 143, 637, 899, 1042} }, + // { 12 << 7, 5, { 0, 143, 637, 899, 1042} }, // marwa (From yarns source code) { 12 << 7, 6, { 0, 143, 494, 755, 1132, 1393} }, // shree (From yarns source code) - { 12 << 7, 7, { 0, 115, 494, 755, 899, 1014, 1393} }, + // { 12 << 7, 7, { 0, 115, 494, 755, 899, 1014, 1393} }, // purvi (From yarns source code) - { 12 << 7, 7, { 0, 143, 494, 755, 899, 1042, 1393} }, + // { 12 << 7, 7, { 0, 143, 494, 755, 899, 1042, 1393} }, // bilawal (From yarns source code) - { 12 << 7, 7, { 0, 261, 494, 637, 899, 1160, 1393} }, + // { 12 << 7, 7, { 0, 261, 494, 637, 899, 1160, 1393} }, // yaman (From yarns source code) { 12 << 7, 7, { 0, 261, 522, 783, 899, 1160, 1421} }, // kafi (From yarns source code) - { 12 << 7, 7, { 0, 233, 376, 637, 899, 1132, 1275} }, + // { 12 << 7, 7, { 0, 233, 376, 637, 899, 1132, 1275} }, // bhimpalasree (From yarns source code) { 12 << 7, 7, { 0, 261, 404, 637, 899, 1160, 1303} }, // darbari (From yarns source code) - { 12 << 7, 7, { 0, 261, 376, 637, 899, 1014, 1275} }, + // { 12 << 7, 7, { 0, 261, 376, 637, 899, 1014, 1275} }, // rageshree (From yarns source code) - { 12 << 7, 7, { 0, 261, 494, 637, 899, 1132, 1275} }, + // { 12 << 7, 7, { 0, 261, 494, 637, 899, 1132, 1275} }, // khamaj (From yarns source code) - { 12 << 7, 8, { 0, 261, 494, 637, 899, 1160, 1275, 1421} }, + // { 12 << 7, 8, { 0, 261, 494, 637, 899, 1160, 1275, 1421} }, // mimal (From yarns source code) - { 12 << 7, 8, { 0, 261, 376, 637, 899, 1132, 1275, 1393} }, + // { 12 << 7, 8, { 0, 261, 376, 637, 899, 1132, 1275, 1393} }, // parameshwari (From yarns source code) - { 12 << 7, 6, { 0, 115, 376, 637, 1132, 1275} }, + // { 12 << 7, 6, { 0, 115, 376, 637, 1132, 1275} }, // rangeshwari (From yarns source code) - { 12 << 7, 6, { 0, 261, 376, 637, 899, 1393} }, + // { 12 << 7, 6, { 0, 261, 376, 637, 899, 1393} }, // gangeshwari (From yarns source code) - { 12 << 7, 6, { 0, 494, 637, 899, 1014, 1275} }, + // { 12 << 7, 6, { 0, 494, 637, 899, 1014, 1275} }, // kameshwari (From yarns source code) - { 12 << 7, 6, { 0, 261, 755, 899, 1132, 1275} }, + // { 12 << 7, 6, { 0, 261, 755, 899, 1132, 1275} }, // pa__kafi (From yarns source code) - { 12 << 7, 7, { 0, 261, 376, 637, 899, 1160, 1275} }, + // { 12 << 7, 7, { 0, 261, 376, 637, 899, 1160, 1275} }, // natbhairav (From yarns source code) - { 12 << 7, 7, { 0, 261, 494, 637, 899, 1014, 1393} }, + // { 12 << 7, 7, { 0, 261, 494, 637, 899, 1014, 1393} }, // m_kauns (From yarns source code) - { 12 << 7, 6, { 0, 261, 522, 637, 1014, 1275} }, + // { 12 << 7, 6, { 0, 261, 522, 637, 1014, 1275} }, // bairagi (From yarns source code) { 12 << 7, 5, { 0, 115, 637, 899, 1275} }, // b_todi (From yarns source code) - { 12 << 7, 5, { 0, 115, 376, 899, 1275} }, + // { 12 << 7, 5, { 0, 115, 376, 899, 1275} }, // chandradeep (From yarns source code) - { 12 << 7, 5, { 0, 376, 637, 899, 1275} }, + // { 12 << 7, 5, { 0, 376, 637, 899, 1275} }, // kaushik_todi (From yarns source code) - { 12 << 7, 5, { 0, 376, 637, 755, 1014} }, + // { 12 << 7, 5, { 0, 376, 637, 755, 1014} }, // jogeshwari (From yarns source code) - { 12 << 7, 6, { 0, 376, 494, 637, 1132, 1275} }, + // { 12 << 7, 6, { 0, 376, 494, 637, 1132, 1275} }, // Tartini-Vallotti [12] - from the Huygens-Fokker Scala scale archive - see http://www.huygens-fokker.org/scala/downloads.html#scales { 12 << 7, 12, { 0, 120, 251, 381, 502, 643, 758, 893, 1019, 1144, 1280, 1395} }, @@ -281,27 +281,27 @@ const Scale scales[] = { // Bohlen-Pierce (lambda) - see https://en.wikipedia.org/wiki/Bohlen–Pierce_scale { 12 << 7, 9, { 0, 244, 351, 470, 714, 822, 1066, 1185, 1428} }, - // 8-24-HD3 (16 step harmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip - { 12 << 7, 16, { 0, 165, 312, 445, 567, 679, 782, 879, 969, 1054, 1134, 1209, 1281, 1349, 1414, 1476} }, - // 7-21-HD3 (14 step harmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip - { 12 << 7, 14, { 0, 187, 351, 499, 632, 754, 865, 969, 1066, 1156, 1241, 1320, 1396, 1468} }, - // 6-18-HD3 (12 step harmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip - { 12 << 7, 12, { 0, 216, 402, 567, 714, 847, 969, 1081, 1185, 1281, 1371, 1456} }, - // 5-15-HD3 (10 step harmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip - { 12 << 7, 10, { 0, 255, 470, 657, 822, 969, 1102, 1224, 1336, 1440} }, - // 4-12-HD3 (8 step harmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip - { 12 << 7, 8, { 0, 312, 567, 782, 969, 1134, 1281, 1414} }, - - // 24-8-HD3 (16 step subharmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip - { 12 << 7, 16, { 0, 60, 122, 187, 255, 327, 402, 482, 567, 657, 754, 857, 969, 1091, 1224, 1371} }, - // 21-7-HD3 (14 step subharmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip - { 12 << 7, 14, { 0, 68, 140, 216, 295, 380, 470, 567, 671, 782, 904, 1037, 1185, 1349} }, - // 18-6-HD3 (12 step subharmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip - { 12 << 7, 12, { 0, 80, 165, 255, 351, 455, 567, 689, 822, 969, 1134, 1320} }, - // 15-5-HD3 (10 step subharmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip - { 12 << 7, 10, { 0, 96, 200, 312, 434, 567, 714, 879, 1066, 1281} }, - // 12-4-HD3 (8 step subharmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip - { 12 << 7, 8, { 0, 122, 255, 402, 567, 754, 969, 1224} } +// // 8-24-HD3 (16 step harmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip +// { 12 << 7, 16, { 0, 165, 312, 445, 567, 679, 782, 879, 969, 1054, 1134, 1209, 1281, 1349, 1414, 1476} }, +// // 7-21-HD3 (14 step harmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip +// { 12 << 7, 14, { 0, 187, 351, 499, 632, 754, 865, 969, 1066, 1156, 1241, 1320, 1396, 1468} }, +// // 6-18-HD3 (12 step harmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip +// { 12 << 7, 12, { 0, 216, 402, 567, 714, 847, 969, 1081, 1185, 1281, 1371, 1456} }, +// // 5-15-HD3 (10 step harmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip +// { 12 << 7, 10, { 0, 255, 470, 657, 822, 969, 1102, 1224, 1336, 1440} }, +// // 4-12-HD3 (8 step harmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip +// { 12 << 7, 8, { 0, 312, 567, 782, 969, 1134, 1281, 1414} }, +// +// // 24-8-HD3 (16 step subharmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip +// { 12 << 7, 16, { 0, 60, 122, 187, 255, 327, 402, 482, 567, 657, 754, 857, 969, 1091, 1224, 1371} }, +// // 21-7-HD3 (14 step subharmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip +// { 12 << 7, 14, { 0, 68, 140, 216, 295, 380, 470, 567, 671, 782, 904, 1037, 1185, 1349} }, +// // 18-6-HD3 (12 step subharmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip +// { 12 << 7, 12, { 0, 80, 165, 255, 351, 455, 567, 689, 822, 969, 1134, 1320} }, +// // 15-5-HD3 (10 step subharmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip +// { 12 << 7, 10, { 0, 96, 200, 312, 434, 567, 714, 879, 1066, 1281} }, +// // 12-4-HD3 (8 step subharmonic series scale on the tritave) - see Xen-Arts VSTi microtuning library at http://www.xen-arts.net/Xen-Arts%20VSTi%20Microtuning%20Library.zip +// { 12 << 7, 8, { 0, 122, 255, 402, 567, 754, 969, 1224} } } ; }// namespace braids diff --git a/software/o_c_REV/frames_poly_lfo.cpp b/software/o_c_REV/frames_poly_lfo.cpp index ce738a9a..aee41e0a 100644 --- a/software/o_c_REV/frames_poly_lfo.cpp +++ b/software/o_c_REV/frames_poly_lfo.cpp @@ -63,6 +63,7 @@ void PolyLfo::Init() { std::fill(&phase_[0], &phase_[kNumChannels], 0); last_phase_difference_ = 0; last_phase_difference_ = 0; + pattern_predictor_.Init(); } /* static */ diff --git a/software/o_c_REV/src/drivers/SH1106_128x64_driver.cpp b/software/o_c_REV/src/drivers/SH1106_128x64_driver.cpp index 06df9238..737be379 100644 --- a/software/o_c_REV/src/drivers/SH1106_128x64_driver.cpp +++ b/software/o_c_REV/src/drivers/SH1106_128x64_driver.cpp @@ -26,6 +26,7 @@ #include #include "SH1106_128x64_driver.h" #include "../../OC_gpio.h" +#include "../../OC_options.h" #define DMA_PAGE_TRANSFER #ifdef DMA_PAGE_TRANSFER @@ -45,18 +46,23 @@ static uint8_t SH1106_data_start_seq[] = { static uint8_t SH1106_init_seq[] = { // u8g_dev_ssd1306_128x64_adafruit3_init_seq - 0x0ae, /* display off, sleep mode */ + 0x0ae, /* display off, sleep mode */ 0x0d5, 0x080, /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */ 0x0a8, 0x03f, /* multiplex ratio, duty = 1/32 */ 0x0d3, 0x000, /* set display offset */ - 0x040, /* start line */ + 0x040, /* start line */ 0x08d, 0x014, /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */ 0x020, 0x000, /* 2012-05-27: page addressing mode */ // PLD: Seems to work in conjuction with lower 4 bits of column data? - 0x0a1, /* segment remap a0/a1*/ - 0x0c8, /* c0: scan dir normal, c8: reverse */ + #ifdef FLIP_180 + 0x0a0, /* segment remap a0/a1*/ + 0x0c0, /* c0: scan dir normal, c8: reverse */ + #else + 0x0a1, /* segment remap a0/a1*/ + 0x0c8, /* c0: scan dir normal, c8: reverse */ + #endif 0x0da, 0x012, /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */ 0x081, 0x0cf, /* [2] set contrast control */ 0x0d9, 0x0f1, /* [2] pre-charge period 0x022/f1*/ @@ -65,7 +71,7 @@ static uint8_t SH1106_init_seq[] = { 0x02e, /* 2012-05-27: Deactivate scroll */ 0x0a4, /* output ram to display */ 0x0a6, /* none inverted normal display mode */ - //0x0af, /* display on */ + //0x0af, /* display on */ }; static uint8_t SH1106_display_on_seq[] = { diff --git a/software/o_c_REV/util/util_integer_sequences.h b/software/o_c_REV/util/util_integer_sequences.h index 4332ddae..775a4234 100644 --- a/software/o_c_REV/util/util_integer_sequences.h +++ b/software/o_c_REV/util/util_integer_sequences.h @@ -133,11 +133,11 @@ class IntegerSequence { x_ = OC::Strings::digsum_of_n[k_]; break; case 6: - x_ = OC::Strings::digsum_of_n_base4[k_]; - break; + x_ = OC::Strings::digsum_of_n_base4[k_]; + break; case 7: - x_ = OC::Strings::digsum_of_n_base5[k_]; - break; + x_ = OC::Strings::digsum_of_n_base5[k_]; + break; case 8: x_ = OC::Strings::count_down_by_2[k_]; break;