diff --git a/software/o_c_REV/APP_A_SEQ.ino b/software/o_c_REV/APP_A_SEQ.ino index 0bfc2b4f..2823079f 100644 --- a/software/o_c_REV/APP_A_SEQ.ino +++ b/software/o_c_REV/APP_A_SEQ.ino @@ -2101,7 +2101,8 @@ void SEQ_downButtonLong() { else { // toggle update behaviour: seq_channel[0x0].toggle_EoS(); seq_channel[0x1].toggle_EoS(); -} } + } +} void SEQ_menu() { diff --git a/software/o_c_REV/APP_POLYLFO.ino b/software/o_c_REV/APP_POLYLFO.ino index 8587d184..3033a452 100644 --- a/software/o_c_REV/APP_POLYLFO.ino +++ b/software/o_c_REV/APP_POLYLFO.ino @@ -172,7 +172,7 @@ SETTINGS_DECLARE(PolyLfo, POLYLFO_SETTING_LAST) { { 0, 0, 1, "Tap tempo", OC::Strings::off_on, settings::STORAGE_TYPE_U8 }, { 0, 0, 255, "Shape", NULL, settings::STORAGE_TYPE_U8 }, { 0, -128, 127, "Shape spread", NULL, settings::STORAGE_TYPE_I8 }, - { -1, -128, 127, "Phase/frq sprd", NULL, settings::STORAGE_TYPE_I8 }, + { 0, -128, 127, "Phase/frq sprd", NULL, settings::STORAGE_TYPE_I8 }, { 0, -128, 127, "Coupling", NULL, settings::STORAGE_TYPE_I8 }, { 230, 0, 230, "Output range", NULL, settings::STORAGE_TYPE_U8 }, { 0, -128, 127, "Offset", NULL, settings::STORAGE_TYPE_I8 }, @@ -220,10 +220,10 @@ void FASTRUN POLYLFO_isr() { int32_t spread = SCALE8_16(poly_lfo.get_spread() + 128) + (poly_lfo.cv_spread.value() * 16); poly_lfo.lfo.set_spread(USAT16(spread)); - int32_t coupling = SCALE8_16(poly_lfo.get_coupling() + 128) + (poly_lfo.cv_coupling.value() * 16); + int32_t coupling = SCALE8_16(poly_lfo.get_coupling() + 127) + (poly_lfo.cv_coupling.value() * 16); poly_lfo.lfo.set_coupling(USAT16(coupling)); - poly_lfo.lfo.set_shape_spread(SCALE8_16(poly_lfo.get_shape_spread() + 128)); + poly_lfo.lfo.set_shape_spread(SCALE8_16(poly_lfo.get_shape_spread() + 127)); poly_lfo.lfo.set_attenuation(SCALE8_16(poly_lfo.get_attenuation())); poly_lfo.lfo.set_offset(SCALE8_16(poly_lfo.get_offset())); @@ -342,8 +342,20 @@ void POLYLFO_handleButtonEvent(const UI::Event &event) { break; } } + + if (UI::EVENT_BUTTON_LONG_PRESS == event.type) { + switch (event.control) { + case OC::CONTROL_BUTTON_DOWN: + poly_lfo.lfo.set_phase_reset_flag(true); + break; + default: + break; + } + } + } + void POLYLFO_handleEncoderEvent(const UI::Event &event) { if (OC::CONTROL_ENCODER_L == event.control) { if (!poly_lfo.get_tap_tempo()) poly_lfo.change_value(poly_lfo_state.left_edit_mode, event.value); diff --git a/software/o_c_REV/frames_poly_lfo.cpp b/software/o_c_REV/frames_poly_lfo.cpp index e21ced01..bcc799e0 100644 --- a/software/o_c_REV/frames_poly_lfo.cpp +++ b/software/o_c_REV/frames_poly_lfo.cpp @@ -58,6 +58,8 @@ void PolyLfo::Init() { std::fill(&value_[0], &value_[kNumChannels], 0); std::fill(&wt_value_[0], &wt_value_[kNumChannels], 0); std::fill(&phase_[0], &phase_[kNumChannels], 0); + last_phase_difference_ = 0; + last_phase_difference_ = 0; } /* static */ @@ -168,28 +170,31 @@ void PolyLfo::Render(int32_t frequency, bool reset_phase, bool tempo_sync) { } // Advance phasors. - if (freq_div_b_ == POLYLFO_FREQ_MULT_NONE && freq_div_c_ && POLYLFO_FREQ_MULT_NONE && freq_div_c_ == POLYLFO_FREQ_MULT_NONE && !sync_) { - // original Frames behaviour - if (spread_ >= 0) { - uint32_t phase_difference = static_cast(spread_) << 15; - phase_[1] = phase_[0] + phase_difference; - phase_[2] = phase_[1] + phase_difference; - phase_[3] = phase_[2] + phase_difference; + if (spread_ >= 0) { + phase_difference_ = static_cast(spread_) << 15; + if (freq_div_b_ == POLYLFO_FREQ_MULT_NONE) { + phase_[1] = phase_[0] + phase_difference_; } else { - for (uint8_t i = 1; i < kNumChannels; ++i) { - phase_[i] += FrequencyToPhaseIncrement(frequency, freq_range_); - frequency -= 5040 * spread_ >> 15; - } + phase_[1] = phase_[1] - last_phase_difference_ + phase_difference_; + } + if (freq_div_c_ == POLYLFO_FREQ_MULT_NONE) { + phase_[2] = phase_[0] + (2 * phase_difference_); + } else { + phase_[2] = phase_[2] - last_phase_difference_ + phase_difference_; + } + if (freq_div_d_ == POLYLFO_FREQ_MULT_NONE) { + phase_[3] = phase_[0] + (3 * phase_difference_); + } else { + phase_[3] = phase_[3] - last_phase_difference_ + phase_difference_; } } else { - // if frequency division or tap-tempo is in use - if (spread_ > 10) { - uint32_t phase_difference = static_cast(spread_ - 10) << 2; - phase_[1] = phase_[1] + phase_difference; - phase_[2] = phase_[2] + phase_difference; - phase_[3] = phase_[3] + phase_difference; + for (uint8_t i = 1; i < kNumChannels; ++i) { + // phase_[i] += FrequencyToPhaseIncrement(frequency, freq_range_); + phase_[i] -= i * (phase_increment_ch1_ >> 16) * spread_ ; + // frequency -= 5040 * spread_ >> 15; } } + last_phase_difference_ = phase_difference_; } const uint8_t* sine = &wt_lfo_waveforms[17 * 257]; diff --git a/software/o_c_REV/frames_poly_lfo.h b/software/o_c_REV/frames_poly_lfo.h index 70037872..a63deff5 100644 --- a/software/o_c_REV/frames_poly_lfo.h +++ b/software/o_c_REV/frames_poly_lfo.h @@ -145,7 +145,7 @@ class PolyLfo { } inline void set_shape_spread(uint16_t shape_spread) { - shape_spread_ = static_cast(shape_spread - 32768) >> 1; + shape_spread_ = static_cast(shape_spread - 32767) >> 1; } inline void set_spread(uint16_t spread) { @@ -221,6 +221,10 @@ class PolyLfo { } } + inline void set_phase_reset_flag(bool reset) { + phase_reset_flag_ = reset; + } + inline void set_sync(bool sync) { sync_ = sync; } @@ -280,8 +284,9 @@ class PolyLfo { stmlib::PatternPredictor<32, 8> pattern_predictor_; uint32_t period_; uint32_t sync_phase_increment_; - - + uint32_t phase_difference_ ; + uint32_t last_phase_difference_ ; + DISALLOW_COPY_AND_ASSIGN(PolyLfo); };