BogaudioModules

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

commit a76c24aeba9b3fc966d0b53584136ad0c756b500
parent 247cd235c06c4ab32cbc274ff1b65233d0bfcabe
Author: Matt Demanett <matt@demanett.net>
Date:   Sat, 14 Apr 2018 22:43:38 -0400

Fix feedback FM.

Diffstat:
Mres-src/FMOp-src.svg | 8++++----
Mres/FMOp.svg | 0
Msrc/EightFO.cpp | 2+-
Msrc/FMOp.cpp | 11+++++++----
Msrc/FMOp.hpp | 1+
Msrc/LFO.cpp | 2+-
Msrc/Test.cpp | 24+++++-------------------
Msrc/Test.hpp | 7+++----
Msrc/XCO.cpp | 4++--
Msrc/XCO.hpp | 1+
10 files changed, 25 insertions(+), 35 deletions(-)

diff --git a/res-src/FMOp-src.svg b/res-src/FMOp-src.svg @@ -316,13 +316,13 @@ <text font-size="6pt" letter-spacing="1px" transform="translate(1 40)">V/OCT</text> </g> <g transform="translate(34 0)"> - <use id="GATE_INPUT" xlink:href="#input" transform="translate(3 5)" /> - <text font-size="6pt" letter-spacing="1px" transform="translate(3 40)">GATE</text> - </g> - <g transform="translate(66 0)"> <use id="FM_INPUT" xlink:href="#input" transform="translate(3 5)" /> <text font-size="6pt" letter-spacing="1px" transform="translate(8.5 40)">FM</text> </g> + <g transform="translate(66 0)"> + <use id="GATE_INPUT" xlink:href="#input" transform="translate(3 5)" /> + <text font-size="6pt" letter-spacing="1px" transform="translate(3 40)">GATE</text> + </g> <g transform="translate(98 0)"> <use id="AUDIO_OUTPUT" xlink:href="#output" transform="translate(3 5)" /> <text font-size="6pt" letter-spacing="1px" transform="translate(6 40)">OUT</text> diff --git a/res/FMOp.svg b/res/FMOp.svg Binary files differ. diff --git a/src/EightFO.cpp b/src/EightFO.cpp @@ -92,7 +92,7 @@ void EightFO::step() { _phase0Offset = phaseOffset(params[PHASE0_PARAM], inputs[PHASE0_INPUT], basePhase0Offset); } - _phasor.next(); + _phasor.advancePhase(); bool useSample = true; ++_sampleStep; if (_sampleStep >= _sampleSteps) { diff --git a/src/FMOp.cpp b/src/FMOp.cpp @@ -105,7 +105,10 @@ void FMOp::step() { feedback *= envelope; } - float offset = feedback * _phasor._phase; + float offset = 0.0f; + if (feedback > 0.001f) { + offset = feedback * _feedbackDelayedSample; + } if (inputs[FM_INPUT].active) { offset += inputs[FM_INPUT].value * _depth * 2.0f; } @@ -119,7 +122,7 @@ void FMOp::step() { if (_levelEnvelopeOn) { out *= envelope; } - outputs[AUDIO_OUTPUT].value = amplitude * out; + outputs[AUDIO_OUTPUT].value = _feedbackDelayedSample = amplitude * out; } struct FMOpWidget : ModuleWidget { @@ -156,8 +159,8 @@ struct FMOpWidget : ModuleWidget { auto levelInputPosition = Vec(79.0, 274.0); auto sustainInputPosition = Vec(111.0, 274.0); auto pitchInputPosition = Vec(15.0, 318.0); - auto gateInputPosition = Vec(47.0, 318.0); - auto fmInputPosition = Vec(79.0, 318.0); + auto fmInputPosition = Vec(47.0, 318.0); + auto gateInputPosition = Vec(79.0, 318.0); auto audioOutputPosition = Vec(111.0, 318.0); diff --git a/src/FMOp.hpp b/src/FMOp.hpp @@ -54,6 +54,7 @@ struct FMOp : Module { static constexpr int oversample = 8; int _steps = 0; float _feedback = 0.0f; + float _feedbackDelayedSample = 0.0f; float _depth = 0.0f; float _level = 0.0f; bool _envelopeOn = false; diff --git a/src/LFO.cpp b/src/LFO.cpp @@ -77,7 +77,7 @@ void LFO::step() { } } - _phasor.next(); + _phasor.advancePhase(); bool useSample = true; ++_sampleStep; if (_sampleStep >= _sampleSteps) { diff --git a/src/Test.cpp b/src/Test.cpp @@ -297,26 +297,12 @@ void Test::step() { #elif FEEDBACK_PM _carrier.setSampleRate(engineGetSampleRate()); _carrier.setFrequency(oscillatorPitch()); - float feedback = params[PARAM3_PARAM].value; - if (inputs[CV3_INPUT].active) { - feedback *= clamp(inputs[CV3_INPUT].value, 0.0f, 10.0f) / 10.0f; + float feedback = params[PARAM2_PARAM].value; + if (inputs[CV2_INPUT].active) { + feedback *= clamp(inputs[CV2_INPUT].value, 0.0f, 10.0f) / 10.0f; } - // feedback *= 10.0f; - - // no delay: - feedback *= _carrier.next(); - - // // 1 sample: - // feedback *= _carrier.current(); - // _carrier.next(); - - // // 2 samples averaged: - // float feedbackSample = _carrier.current(); - // _carrier.next(); - // feedback *= (_feedbackSample + feedbackSample) / 2.0f; - // _feedbackSample = feedbackSample; - - outputs[OUT_OUTPUT].value = _carrierOutput.nextFromPhasor(_carrier, Phasor::radiansToPhase(feedback)) * 5.0f; + _carrier.advancePhase(); + outputs[OUT_OUTPUT].value = _feedbackSample = _carrier.nextFromPhasor(_carrier, Phasor::radiansToPhase(feedback * _feedbackSample)) * 5.0f; #elif EG _envelope.setSampleRate(engineGetSampleRate()); diff --git a/src/Test.hpp b/src/Test.hpp @@ -15,10 +15,10 @@ extern Model* modelTest; // #define SINEBANK 1 // #define OVERSAMPLING 1 // #define OVERSAMPLED_BL 1 -#define ANTIALIASING 1 +// #define ANTIALIASING 1 // #define FM 1 // #define PM 1 -// #define FEEDBACK_PM 1 +#define FEEDBACK_PM 1 // #define EG 1 // #define TABLES 1 @@ -158,8 +158,7 @@ struct Test : Module { SineTableOscillator _modulator; SineTableOscillator _carrier; #elif FEEDBACK_PM - Phasor _carrier; - SineTableOscillator _carrierOutput; + SineTableOscillator _carrier; float _feedbackSample = 0.0f; #elif EG ADSR _envelope; diff --git a/src/XCO.cpp b/src/XCO.cpp @@ -131,7 +131,7 @@ void XCO::step() { float sawOut = 0.0f; float triangleOut = 0.0f; float sineOut = 0.0f; - float sineFeedbackOffset = sineFeedback ? Phasor::radiansToPhase(_sineFeedback * _phasor._phase) : 0.0f; + float sineFeedbackOffset = sineFeedback ? Phasor::radiansToPhase(_sineFeedback * _sineFeedbackDelayedSample) : 0.0f; if (squareOversample || sawOversample || triangleOversample || sineOversample) { for (int i = 0; i < oversample; ++i) { @@ -185,7 +185,7 @@ void XCO::step() { outputs[SQUARE_OUTPUT].value = squareOut; outputs[SAW_OUTPUT].value = sawOut; outputs[TRIANGLE_OUTPUT].value = triangleOut; - outputs[SINE_OUTPUT].value = sineOut; + outputs[SINE_OUTPUT].value = _sineFeedbackDelayedSample = sineOut; outputs[MIX_OUTPUT].value = squareOut + sawOut + triangleOut + sineOut; } diff --git a/src/XCO.hpp b/src/XCO.hpp @@ -78,6 +78,7 @@ struct XCO : Module { bool _fmLinearMode = false; float _triangleSampleWidth = 0.0f; float _sineFeedback = 0.0f; + float _sineFeedbackDelayedSample = 0.0f; float _squarePhaseOffset = 0.0f; float _sawPhaseOffset = 0.0f; float _trianglePhaseOffset = 0.0f;