BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

commit cc75739f528cb89a9e8b9063dace0d5b81f7f64f
parent e357d616c23128ac789cc0d8fec54483667abf4d
Author: Matt Demanett <matt@demanett.net>
Date:   Thu, 23 Sep 2021 22:08:31 -0400

LVCO: add option to reset the phase on waveform change. #182

Diffstat:
MREADME-prerelease.md | 2++
Msrc/LVCO.cpp | 33+++++++++++++++++++++++++--------
Msrc/LVCO.hpp | 4+++-
3 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/README-prerelease.md b/README-prerelease.md @@ -86,6 +86,8 @@ _Polyphony:_ <a href="#polyphony">Polyphonic</a>, with channels defined by the V A 3HP subset of VCO, designed as a compact general-purpose oscillator. The waveform is selectable between sine, triangle, saw, square and 25% and 10% duty-cycle pulses. FM and linear modes are selectable on the context menu. +Context menu option "Reset phase on wave change", if enabled, causes the waveform phase to be set to zero when the waveform is changed. By default the continues to advance from wherever it was. + _Polyphony:_ Same as VCO. #### <a name="sine"></a> SINE diff --git a/src/LVCO.cpp b/src/LVCO.cpp @@ -3,11 +3,13 @@ #define FM_MODE "fm_mode" #define LINEAR_MODE "linear_mode" +#define RESET_ON_WAVE_CHANGE "reset_on_wave_change" json_t* LVCO::toJson(json_t* root) { root = VCOBase::toJson(root); json_object_set_new(root, FM_MODE, json_boolean(_fmLinearMode)); json_object_set_new(root, LINEAR_MODE, json_boolean(_linearMode)); + json_object_set_new(root, RESET_ON_WAVE_CHANGE, json_boolean(_resetOnWaveChange)); return root; } @@ -23,6 +25,11 @@ void LVCO::fromJson(json_t* root) { if (l) { _linearMode = json_is_true(l); } + + json_t* rowc = json_object_get(root, RESET_ON_WAVE_CHANGE); + if (rowc) { + _resetOnWaveChange = json_boolean_value(rowc); + } } bool LVCO::active() { @@ -31,8 +38,17 @@ bool LVCO::active() { void LVCO::modulate() { _slowMode = params[SLOW_PARAM].getValue() > 0.5f; - _wave = (Wave)params[WAVE_PARAM].getValue(); _fmDepth = params[FM_DEPTH_PARAM].getValue(); + + Wave wave = (Wave)(1 + (int)params[WAVE_PARAM].getValue()); + if (_wave != wave) { + _wave = wave; + if (_resetOnWaveChange) { + for (int c = 0; c < _channels; c++) { + _engines[c]->phasor.setPhase(0.0f); + } + } + } } void LVCO::modulateChannel(int c) { @@ -65,13 +81,12 @@ void LVCO::modulateChannel(int c) { } void LVCO::processAlways(const ProcessArgs& args) { - Wave wave = (Wave)params[WAVE_PARAM].getValue(); - lights[SINE_LIGHT].value = wave == SINE_WAVE; - lights[TRIANGLE_LIGHT].value = wave == TRIANGLE_WAVE; - lights[SAW_LIGHT].value = wave == SAW_WAVE; - lights[SQUARE_LIGHT].value = wave == SQUARE_WAVE; - lights[PULSE_25_LIGHT].value = wave == PULSE_25_WAVE; - lights[PULSE_10_LIGHT].value = wave == PULSE_10_WAVE; + lights[SINE_LIGHT].value = _wave == SINE_WAVE; + lights[TRIANGLE_LIGHT].value = _wave == TRIANGLE_WAVE; + lights[SAW_LIGHT].value = _wave == SAW_WAVE; + lights[SQUARE_LIGHT].value = _wave == SQUARE_WAVE; + lights[PULSE_25_LIGHT].value = _wave == PULSE_25_WAVE; + lights[PULSE_10_LIGHT].value = _wave == PULSE_10_WAVE; } void LVCO::processChannel(const ProcessArgs& args, int c) { @@ -141,6 +156,8 @@ struct LVCOWidget : VCOBaseModuleWidget { menu->addChild(new BoolOptionMenuItem("Linear frequency mode", [m]() { return &m->_linearMode; })); + menu->addChild(new BoolOptionMenuItem("Reset phase on wave change", [m]() { return &m->_resetOnWaveChange; })); + OptionsMenuItem* p = new OptionsMenuItem("Polyphony channels from"); p->addItem(OptionMenuItem("V/OCT input", [m]() { return m->_polyInputID == LVCO::PITCH_INPUT; }, [m]() { m->_polyInputID = LVCO::PITCH_INPUT; })); p->addItem(OptionMenuItem("FM input", [m]() { return m->_polyInputID == LVCO::FM_INPUT; }, [m]() { m->_polyInputID = LVCO::FM_INPUT; })); diff --git a/src/LVCO.hpp b/src/LVCO.hpp @@ -39,6 +39,7 @@ struct LVCO : VCOBase { }; enum Wave { + UNINITIALIZED_WAVE, SINE_WAVE, TRIANGLE_WAVE, SAW_WAVE, @@ -47,7 +48,8 @@ struct LVCO : VCOBase { PULSE_10_WAVE }; - Wave _wave = SINE_WAVE; + Wave _wave = UNINITIALIZED_WAVE; + bool _resetOnWaveChange = false; LVCO() : VCOBase(