BogaudioModules

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

commit 25a9e6ae09fdcda00d66438eefa28aa6c93b6cad
parent bd6ba87a4f13c4dfe52405d297feaf337ad351d0
Author: Matt Demanett <matt@demanett.net>
Date:   Thu, 19 Apr 2018 20:45:29 -0400

Fix hard sync; fix Additator had sync and pitch inputs swapped.

Diffstat:
Msrc/Additator.cpp | 10+++++-----
Msrc/Additator.hpp | 3++-
Msrc/EightFO.cpp | 8++++----
Msrc/EightFO.hpp | 3++-
Msrc/LFO.cpp | 6+++---
Msrc/LFO.hpp | 3++-
Msrc/VCO.cpp | 8++++----
Msrc/VCO.hpp | 3++-
Msrc/XCO.cpp | 8++++----
Msrc/XCO.hpp | 3++-
Msrc/dsp/oscillator.cpp | 4++++
Msrc/dsp/oscillator.hpp | 1+
Asrc/dsp/signal.cpp | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/dsp/signal.hpp | 32++++++++++++++++++++++++++++++++
14 files changed, 109 insertions(+), 25 deletions(-)

diff --git a/src/Additator.cpp b/src/Additator.cpp @@ -118,9 +118,6 @@ void Additator::step() { frequency = clamp(cvToFrequency(frequency), 20.0f, _maxFrequency); _oscillator.setFrequency(frequency); - if (_syncTrigger.process(inputs[SYNC_INPUT].value)) { - _oscillator.syncToPhase(_phase == PHASE_SINE ? 0.0f : M_PI / 2.0f); - } Phase phase = params[PHASE_PARAM].value > 1.5f ? PHASE_COSINE : PHASE_SINE; if (_phase != phase) { _phase = phase; @@ -128,6 +125,9 @@ void Additator::step() { } } + if (_syncTrigger.next(inputs[SYNC_INPUT].value)) { + _oscillator.syncToPhase(_phase == PHASE_SINE ? 0.0f : M_PI / 2.0f); + } outputs[AUDIO_OUTPUT].value = _oscillator.next() * 5.0; } @@ -160,12 +160,12 @@ struct AdditatorWidget : ModuleWidget { auto filterParamPosition = Vec(184.0, 218.0); auto phaseParamPosition = Vec(194.0, 299.0); - auto pitchInputPosition = Vec(16.0, 274.0); + auto syncInputPosition = Vec(16.0, 274.0); auto partialsInputPosition = Vec(50.0, 274.0); auto widthInputPosition = Vec(84.0, 274.0); auto oddSkewInputPosition = Vec(118.0, 274.0); auto evenSkewInputPosition = Vec(152.0, 274.0); - auto syncInputPosition = Vec(16.0, 318.0); + auto pitchInputPosition = Vec(16.0, 318.0); auto gainInputPosition = Vec(50.0, 318.0); auto decayInputPosition = Vec(84.0, 318.0); auto balanceInputPosition = Vec(118.0, 318.0); diff --git a/src/Additator.hpp b/src/Additator.hpp @@ -3,6 +3,7 @@ #include "bogaudio.hpp" #include "dsp/oscillator.hpp" #include "dsp/pitch.hpp" +#include "dsp/signal.hpp" using namespace bogaudio::dsp; @@ -80,7 +81,7 @@ struct Additator : Module { Phase _phase = PHASE_RESET; float _maxFrequency = 0.0f; SineBankOscillator _oscillator; - SchmittTrigger _syncTrigger; + PositiveZeroCrossing _syncTrigger; Additator() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) diff --git a/src/EightFO.cpp b/src/EightFO.cpp @@ -80,10 +80,6 @@ void EightFO::step() { _scale *= clamp(inputs[SCALE_INPUT].value / 10.0f, 0.0f, 1.0f); } - if (_resetTrigger.process(inputs[RESET_INPUT].value)) { - _phasor.setPhase(0.0f); - } - _phase7Offset = phaseOffset(params[PHASE7_PARAM], inputs[PHASE7_INPUT], basePhase7Offset); _phase6Offset = phaseOffset(params[PHASE6_PARAM], inputs[PHASE6_INPUT], basePhase6Offset); _phase5Offset = phaseOffset(params[PHASE5_PARAM], inputs[PHASE5_INPUT], basePhase5Offset); @@ -94,6 +90,10 @@ void EightFO::step() { _phase0Offset = phaseOffset(params[PHASE0_PARAM], inputs[PHASE0_INPUT], basePhase0Offset); } + if (_resetTrigger.next(inputs[RESET_INPUT].value)) { + _phasor.resetPhase(); + } + _phasor.advancePhase(); bool useSample = false; if (_sampleSteps > 1) { diff --git a/src/EightFO.hpp b/src/EightFO.hpp @@ -2,6 +2,7 @@ #include "bogaudio.hpp" #include "dsp/oscillator.hpp" +#include "dsp/signal.hpp" using namespace bogaudio::dsp; @@ -89,7 +90,7 @@ struct EightFO : Module { int _sampleStep = 0; float _offset = 0.0f; float _scale = 0.0f; - SchmittTrigger _resetTrigger; + PositiveZeroCrossing _resetTrigger; Phasor _phasor; SineTableOscillator _sine; diff --git a/src/LFO.cpp b/src/LFO.cpp @@ -71,10 +71,10 @@ void LFO::step() { if (inputs[SCALE_INPUT].active) { _scale *= clamp(inputs[SCALE_INPUT].value / 10.0f, 0.0f, 1.0f); } + } - if (_resetTrigger.process(inputs[RESET_INPUT].value)) { - _phasor.setPhase(0.0f); - } + if (_resetTrigger.next(inputs[RESET_INPUT].value)) { + _phasor.resetPhase(); } _phasor.advancePhase(); diff --git a/src/LFO.hpp b/src/LFO.hpp @@ -2,6 +2,7 @@ #include "bogaudio.hpp" #include "dsp/oscillator.hpp" +#include "dsp/signal.hpp" using namespace bogaudio::dsp; @@ -53,7 +54,7 @@ struct LFO : Module { int _sampleStep = 0; float _offset = 0.0f; float _scale = 0.0f; - SchmittTrigger _resetTrigger; + PositiveZeroCrossing _resetTrigger; Phasor _phasor; SineTableOscillator _sine; diff --git a/src/VCO.cpp b/src/VCO.cpp @@ -39,10 +39,6 @@ void VCO::step() { } _baseHz = cvToFrequency(_baseVOct); - if (_syncTrigger.process(inputs[SYNC_INPUT].value)) { - _phasor.setPhase(0.0f); - } - float pw = params[PW_PARAM].value; if (inputs[PW_INPUT].active) { pw *= clamp(inputs[PW_INPUT].value / 5.0f, -1.0f, 1.0f); @@ -55,6 +51,10 @@ void VCO::step() { _fmDepth = params[FM_PARAM].value; } + if (_syncTrigger.next(inputs[SYNC_INPUT].value)) { + _phasor.resetPhase(); + } + float frequency = _baseHz; Phasor::phase_delta_t phaseOffset = 0; if (inputs[FM_INPUT].active && _fmDepth > 0.01f) { diff --git a/src/VCO.hpp b/src/VCO.hpp @@ -3,6 +3,7 @@ #include "bogaudio.hpp" #include "dsp/filter.hpp" #include "dsp/oscillator.hpp" +#include "dsp/signal.hpp" using namespace bogaudio::dsp; @@ -53,7 +54,7 @@ struct VCO : Module { bool _slowMode = false; float _fmDepth = 0.0f; bool _fmLinearMode = false; - SchmittTrigger _syncTrigger; + PositiveZeroCrossing _syncTrigger; Phasor _phasor; BandLimitedSquareOscillator _square; diff --git a/src/XCO.cpp b/src/XCO.cpp @@ -40,10 +40,6 @@ void XCO::step() { } _baseHz = cvToFrequency(_baseVOct); - if (_syncTrigger.process(inputs[SYNC_INPUT].value)) { - _phasor.setPhase(0.0f); - } - float pw = params[SQUARE_PW_PARAM].value; if (inputs[SQUARE_PW_INPUT].active) { pw *= clamp(inputs[SQUARE_PW_INPUT].value / 5.0f, -1.0f, 1.0f); @@ -86,6 +82,10 @@ void XCO::step() { _sineMix = level(params[SINE_MIX_PARAM], inputs[SINE_MIX_INPUT]); } + if (_syncTrigger.next(inputs[SYNC_INPUT].value)) { + _phasor.resetPhase(); + } + float frequency = _baseHz; Phasor::phase_delta_t phaseOffset = 0; if (inputs[FM_INPUT].active && _fmDepth > 0.01f) { diff --git a/src/XCO.hpp b/src/XCO.hpp @@ -3,6 +3,7 @@ #include "bogaudio.hpp" #include "dsp/filter.hpp" #include "dsp/oscillator.hpp" +#include "dsp/signal.hpp" using namespace bogaudio::dsp; @@ -88,7 +89,7 @@ struct XCO : Module { float _sawMix = 1.0f; float _triangleMix = 1.0f; float _sineMix = 1.0f; - SchmittTrigger _syncTrigger; + PositiveZeroCrossing _syncTrigger; Phasor _phasor; BandLimitedSquareOscillator _square; diff --git a/src/dsp/oscillator.cpp b/src/dsp/oscillator.cpp @@ -22,6 +22,10 @@ void Phasor::setSampleWidth(float sw) { } } +void Phasor::resetPhase() { + _phase = 0; +} + void Phasor::setPhase(float radians) { _phase = radiansToPhase(radians); } diff --git a/src/dsp/oscillator.hpp b/src/dsp/oscillator.hpp @@ -86,6 +86,7 @@ struct Phasor : OscillatorGenerator { } void setSampleWidth(float sw); + void resetPhase(); void setPhase(float radians); float nextFromPhasor(const Phasor& phasor, phase_delta_t offset = 0); inline float nextForPhase(phase_t phase) { return _nextForPhase(phase); } diff --git a/src/dsp/signal.cpp b/src/dsp/signal.cpp @@ -0,0 +1,42 @@ + +#include "signal.hpp" + +using namespace bogaudio::dsp; + +bool PositiveZeroCrossing::next(float sample) { + switch (_state) { + case NEGATIVE_STATE: { + if (sample > positiveThreshold) { + _state = POSITIVE_STATE; + return true; + } + break; + } + case POSITIVE_STATE: { + if (sample < negativeThreshold) { + _state = NEGATIVE_STATE; + } + else if (sample < positiveThreshold && _triggerable) { + _state = COUNT_ZEROES_STATE; + _zeroCount = 1; + } + break; + } + case COUNT_ZEROES_STATE: { + if (sample >= negativeThreshold) { + if (++_zeroCount >= zeroesForReset) { + _state = NEGATIVE_STATE; + } + } + else { + _state = NEGATIVE_STATE; + } + break; + } + } + return false; +} + +void PositiveZeroCrossing::reset() { + _state = NEGATIVE_STATE; +} diff --git a/src/dsp/signal.hpp b/src/dsp/signal.hpp @@ -0,0 +1,32 @@ +#pragma once + +namespace bogaudio { +namespace dsp { + +struct PositiveZeroCrossing { + const float positiveThreshold = 0.01f; + const float negativeThreshold = -positiveThreshold; + const int zeroesForReset = 20; + + enum State { + NEGATIVE_STATE, + POSITIVE_STATE, + COUNT_ZEROES_STATE + }; + + State _state; + bool _triggerable; + int _zeroCount = 0; + + PositiveZeroCrossing(bool triggerable = true) + : _triggerable(triggerable) + { + reset(); + } + + bool next(float sample); + void reset(); +}; + +} // namespace dsp +} // namespace bogaudio