BogaudioModules

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

commit b60341887c74ce57b11d3621bc4f2057008fd812
parent b9de1058b50ed44df3b6b8d540f208081ed65776
Author: Matt Demanett <matt@demanett.net>
Date:   Thu, 19 Apr 2018 01:20:12 -0400

Oscillator fixes; add FM depth input to XCO.

Diffstat:
Mres-src/Additator-src.svg | 30+++++++++++++++---------------
Mres-src/XCO-src.svg | 46++++++++++++++++++++++++++--------------------
Mres/Additator.svg | 0
Mres/XCO.svg | 0
Mres/knob_38px.svg | 0
Msrc/Additator.cpp | 14+++++++++-----
Msrc/Additator.hpp | 5++++-
Msrc/EightFO.cpp | 18++++++++++++------
Msrc/FMOp.cpp | 2+-
Msrc/LFO.cpp | 18+++++++++++-------
Msrc/XCO.cpp | 27++++++++++++++++-----------
Msrc/XCO.hpp | 3++-
Msrc/dsp/oscillator.hpp | 3++-
13 files changed, 98 insertions(+), 68 deletions(-)

diff --git a/res-src/Additator-src.svg b/res-src/Additator-src.svg @@ -139,15 +139,15 @@ <symbol id="knobguide-partials" viewBox="0 0 70px 70px"> <g transform="translate(35 35)"> <text font-size="6.0pt" transform="rotate(-240) translate(25.5 0) rotate(240) translate(-2.5 2.5)">1</text> - <polyline points="0,0 3,0" stroke-width="0.3" stroke="#333" transform="rotate(-210) translate(21 0)" /> - <text font-size="6.0pt" transform="rotate(-180) translate(25 0) rotate(180) translate(-7 2.5)">20</text> - <polyline points="0,0 3,0" stroke-width="0.3" stroke="#333" transform="rotate(-150) translate(21 0)" /> - <text font-size="6.0pt" transform="rotate(-120) translate(25 0) rotate(120) translate(-7 2.5)">40</text> - <polyline points="0,0 3,0" stroke-width="0.3" stroke="#333" transform="rotate(-90) translate(21 0)" /> - <text font-size="6.0pt" transform="rotate(-60) translate(25 0) rotate(60) translate(-3 2.5)">60</text> - <polyline points="0,0 3,0" stroke-width="0.3" stroke="#333" transform="rotate(-30) translate(21 0)" /> - <text font-size="6.0pt" transform="rotate(0) translate(25 0) rotate(0) translate(-2.5 2.5)">80</text> - <polyline points="0,0 3,0" stroke-width="0.3" stroke="#333" transform="rotate(30) translate(21 0)" /> + <polyline points="0,0 3,0" stroke-width="0.3" stroke="#333" transform="rotate(-212.73) translate(21 0)" /> + <text font-size="6.0pt" transform="rotate(-182.42) translate(25 0) rotate(182.42) translate(-7 2.8)">20</text> + <polyline points="0,0 3,0" stroke-width="0.3" stroke="#333" transform="rotate(-152.12) translate(21 0)" /> + <text font-size="6.0pt" transform="rotate(-121.82) translate(25 0) rotate(121.82) translate(-7 2.5)">40</text> + <polyline points="0,0 3,0" stroke-width="0.3" stroke="#333" transform="rotate(-91.52) translate(21 0)" /> + <text font-size="6.0pt" transform="rotate(-61.21) translate(25 0) rotate(61.21) translate(-3 2.5)">60</text> + <polyline points="0,0 3,0" stroke-width="0.3" stroke="#333" transform="rotate(-30.91) translate(21 0)" /> + <text font-size="6.0pt" transform="rotate(-0.61) translate(25 0) rotate(0.61) translate(-2.5 2.8)">80</text> + <polyline points="0,0 3,0" stroke-width="0.3" stroke="#333" transform="rotate(29.7) translate(21 0)" /> <text font-size="6.0pt" transform="rotate(60) translate(25.5 0) rotate(-60) translate(-2 2.5)">100</text> </g> </symbol> @@ -277,7 +277,7 @@ <g transform="translate(144 60)"> <!-- <polyline points="0,19 68,19" stroke="#0f0" stroke-width="1" fill="none" /> --> - <!-- <polyline points="39,-20 39,50" stroke="#0f0" stroke-width="1" fill="none" /> --> + <!-- <polyline points="40,-20 40,50" stroke="#0f0" stroke-width="1" fill="none" /> --> <text font-size="8pt" letter-spacing="2px" transform="translate(4 50) rotate(270)">PARTIALS</text> <use id="PARTIALS_PARAM" xlink:href="#knob" transform="translate(21 0)" /> <use xlink:href="#knobguide-partials" transform="translate(5 -16)" /> @@ -357,8 +357,8 @@ <g transform="translate(10 0)"> <g transform="translate(3 0)"> - <use id="PITCH_INPUT" xlink:href="#input" transform="translate(3 5)" /> - <text font-size="6pt" letter-spacing="1px" transform="translate(1 40)">V/OCT</text> + <use id="SYNC_INPUT" xlink:href="#input" transform="translate(3 5)" /> + <text font-size="6pt" letter-spacing="1px" transform="translate(3 40)">SYNC</text> </g> <g transform="translate(37 0)"> <use id="PARTIALS_INPUT" xlink:href="#input" transform="translate(3 5)" /> @@ -366,7 +366,7 @@ </g> <g transform="translate(71 0)"> <use id="WIDTH_INPUT" xlink:href="#input" transform="translate(3 5)" /> - <text font-size="6pt" letter-spacing="1px" transform="translate(0 40)">WIDTH</text> + <text font-size="6pt" letter-spacing="1px" transform="translate(0.5 40)">WIDTH</text> </g> <g transform="translate(105 0)"> <use id="ODD_SKEW_INPUT" xlink:href="#input" transform="translate(3 5)" /> @@ -380,8 +380,8 @@ <g transform="translate(10 44)"> <g transform="translate(3 0)"> - <use id="SYNC_INPUT" xlink:href="#input" transform="translate(3 5)" /> - <text font-size="6pt" letter-spacing="1px" transform="translate(3 40)">SYNC</text> + <use id="PITCH_INPUT" xlink:href="#input" transform="translate(3 5)" /> + <text font-size="6pt" letter-spacing="1px" transform="translate(1 40)">V/OCT</text> </g> <g transform="translate(37 0)"> <use id="GAIN_INPUT" xlink:href="#input" transform="translate(3 5)" /> diff --git a/res-src/XCO-src.svg b/res-src/XCO-src.svg @@ -258,22 +258,28 @@ <g transform="translate(4 0)"> <!-- <polyline points="-50,0 100,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(0 19)" /> --> <text font-size="8pt" letter-spacing="2px" transform="translate(9 27) rotate(270)">FM</text> - <use id="FM_PARAM" xlink:href="#knob" transform="translate(20 0)" /> + <use id="FM_DEPTH_PARAM" xlink:href="#knob" transform="translate(20 0)" /> </g> <!-- <rect width="90" height="10" fill="#0f0" transform="translate(0 26)" /> --> - <g transform="translate(6 52)"> - <g transform="translate(0 0)"> - <!-- <rect width="62" height="47" stroke="#0f0" fill="none" transform="translate(0 0)" /> --> - <!-- <polyline points="0,23.5 100,23.5" stroke="#0f0" stroke-width="1" fill="none" /> --> - <!-- <polyline points="15,23.5 15,-123.5" stroke="#0f0" stroke-width="1" fill="none" /> --> - <rect width="30" height="47" rx="5" fill="#fafafa" /> - <use id="FM_INPUT" xlink:href="#input" transform="translate(3 5)" /> - <text font-size="6pt" letter-spacing="1px" transform="translate(9 40)">FM</text> + <g transform="translate(-19 52)"> + <rect width="71" height="47" rx="5" fill="#fafafa" transform="translate(10 0)" /> + <g transform="translate(10 0)"> + <!-- <rect width="30" height="47" rx="5" fill="#fafafa" /> --> + <use id="FM_INPUT" xlink:href="#input" transform="translate(7 5)" /> + <text font-size="6pt" letter-spacing="1px" transform="translate(11 40)">FM</text> </g> - <g transform="translate(47 9)"> - <text font-size="5pt" letter-spacing="2px" transform="translate(-1 -1)">EXP</text> - <use id="FM_TYPE_PARAM" xlink:href="#switch" transform="translate(0 2)" /> - <text font-size="5pt" letter-spacing="2px" transform="translate(0 34)">LIN</text> + <g transform="translate(47 0)"> + <!-- <rect width="30" height="47" rx="5" fill="#fafafa" /> --> + <use id="FM_DEPTH_INPUT" xlink:href="#input" transform="translate(3 5)" /> + <text font-size="6pt" letter-spacing="1px" transform="translate(0 40)">DEPTH</text> + </g> + <g transform="translate(82 0)"> + <!-- <rect width="30" height="47" rx="5" fill="#00c" /> --> + <g transform="translate(8 9)"> + <text font-size="5pt" letter-spacing="2px" transform="translate(-1 -1)">EXP</text> + <use id="FM_TYPE_PARAM" xlink:href="#switch" transform="translate(0 2)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(0 34)">LIN</text> + </g> </g> </g> </g> @@ -282,7 +288,7 @@ <!-- <rect width="90" height="18" fill="#0f0" transform="translate(0 175)" /> --> <!-- <rect width="90" height="18" fill="#0f0" transform="translate(0 295)" /> --> - <rect width="191" height="47" rx="5" fill="#bbb" transform="translate(99 313)" /> + <rect width="193" height="47" rx="5" fill="#bbb" transform="translate(97 313)" /> <g transform="translate(140 30)"> <rect width="30" height="330" rx="5" fill="#fafafa" /> @@ -443,16 +449,16 @@ <!-- <rect width="30" height="10" fill="#0f0" transform="translate(0 303)" /> --> <g transform="translate(0 313)"> - <rect width="70" height="47" rx="5" fill="#fafafa" transform="translate(10 0)" /> + <rect width="71" height="47" rx="5" fill="#fafafa" transform="translate(10 0)" /> <g transform="translate(10 0)"> <!-- <rect width="30" height="47" rx="5" fill="#fafafa" /> --> - <use id="PITCH_INPUT" xlink:href="#input" transform="translate(4 5)" /> - <text font-size="6pt" letter-spacing="1px" transform="translate(2 40)">V/OCT</text> + <use id="PITCH_INPUT" xlink:href="#input" transform="translate(7 5)" /> + <text font-size="6pt" letter-spacing="1px" transform="translate(5 40)">V/OCT</text> </g> - <g transform="translate(50 0)"> + <g transform="translate(47 0)"> <!-- <rect width="30" height="47" rx="5" fill="#fafafa" /> --> - <use id="SYNC_INPUT" xlink:href="#input" transform="translate(2 5)" /> - <text font-size="6pt" letter-spacing="2px" transform="translate(0 40)">SYNC</text> + <use id="SYNC_INPUT" xlink:href="#input" transform="translate(3 5)" /> + <text font-size="6pt" letter-spacing="1px" transform="translate(3 40)">SYNC</text> </g> <g transform="translate(100 0)"> <!-- <rect width="30" height="47" rx="5" fill="#bbb" transform="translate(0 0)" /> --> diff --git a/res/Additator.svg b/res/Additator.svg Binary files differ. diff --git a/res/XCO.svg b/res/XCO.svg Binary files differ. diff --git a/res/knob_38px.svg b/res/knob_38px.svg Binary files differ. diff --git a/src/Additator.cpp b/src/Additator.cpp @@ -178,9 +178,13 @@ struct AdditatorWidget : ModuleWidget { // end generated by svg_widgets.rb addParam(ParamWidget::create<Knob68>(frequencyParamPosition, module, Additator::FREQUENCY_PARAM, -3.0, 6.0, 0.0)); - addParam(ParamWidget::create<Knob38>(partialsParamPosition, module, Additator::PARTIALS_PARAM, 1.0, module->maxPartials, module->maxPartials / 10.0f)); + { + auto w = ParamWidget::create<Knob38>(partialsParamPosition, module, Additator::PARTIALS_PARAM, 1.0, module->maxPartials, module->maxPartials / 5.0); + dynamic_cast<Knob*>(w)->snap = true; + addParam(w); + } addParam(ParamWidget::create<Knob16>(fineParamPosition, module, Additator::FINE_PARAM, -1.0, 1.0, 0.0)); - addParam(ParamWidget::create<Knob26>(widthParamPosition, module, Additator::WIDTH_PARAM, 0.0, module->maxWidth, module->maxWidth / 2.0f)); + addParam(ParamWidget::create<Knob26>(widthParamPosition, module, Additator::WIDTH_PARAM, 0.0, module->maxWidth, module->maxWidth / 2.0)); addParam(ParamWidget::create<Knob26>(oddSkewParamPosition, module, Additator::ODD_SKEW_PARAM, -module->maxSkew, module->maxSkew, 0.0)); addParam(ParamWidget::create<Knob26>(evenSkewParamPosition, module, Additator::EVEN_SKEW_PARAM, -module->maxSkew, module->maxSkew, 0.0)); addParam(ParamWidget::create<Knob26>( @@ -189,7 +193,7 @@ struct AdditatorWidget : ModuleWidget { Additator::GAIN_PARAM, module->minAmplitudeNormalization, module->maxAmplitudeNormalization, - (module->maxAmplitudeNormalization - module->minAmplitudeNormalization) / 2.0f + module->minAmplitudeNormalization + (module->maxAmplitudeNormalization - module->minAmplitudeNormalization) / 2.0 + module->minAmplitudeNormalization )); addParam(ParamWidget::create<Knob26>( decayParamPosition, @@ -197,7 +201,7 @@ struct AdditatorWidget : ModuleWidget { Additator::DECAY_PARAM, module->minDecay, module->maxDecay, - (module->maxDecay - module->minDecay) / 2.0f + module->minDecay + (module->maxDecay - module->minDecay) / 2.0 + module->minDecay )); addParam(ParamWidget::create<Knob26>(balanceParamPosition, module, Additator::BALANCE_PARAM, -1.0, 1.0, 0.0)); addParam(ParamWidget::create<Knob26>( @@ -206,7 +210,7 @@ struct AdditatorWidget : ModuleWidget { Additator::FILTER_PARAM, module->minFilter, module->maxFilter, - (module->maxFilter - module->minFilter) / 2.0f + module->minFilter + (module->maxFilter - module->minFilter) / 2.0 + module->minFilter )); addParam(ParamWidget::create<StatefulButton9>(phaseParamPosition, module, Additator::PHASE_PARAM, 1.0, 2.0, 1.0)); diff --git a/src/Additator.hpp b/src/Additator.hpp @@ -82,7 +82,10 @@ struct Additator : Module { SineBankOscillator _oscillator; SchmittTrigger _syncTrigger; - Additator() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { + Additator() + : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) + , _oscillator(1000.0f, 100.0f, maxPartials) + { onReset(); onSampleRateChange(); } diff --git a/src/EightFO.cpp b/src/EightFO.cpp @@ -58,6 +58,7 @@ void EightFO::step() { pw = (pw + 1.0f) / 2.0f; pw *= 1.0f - 2.0f * _square.minPulseWidth; _square.setPulseWidth(pw); + _sampleSteps = 1; } else { float sample = abs(params[SAMPLE_PWM_PARAM].value); @@ -66,6 +67,7 @@ void EightFO::step() { } float maxSampleSteps = (_phasor._sampleRate / _phasor._frequency) / 4.0f; _sampleSteps = clamp((int)(sample * maxSampleSteps), 1, (int)maxSampleSteps); + _square.setPulseWidth(SquareOscillator::defaultPulseWidth); } _offset = params[OFFSET_PARAM].value; @@ -93,11 +95,15 @@ void EightFO::step() { } _phasor.advancePhase(); - bool useSample = true; - ++_sampleStep; - if (_sampleStep >= _sampleSteps) { - _sampleStep = 0; - useSample = false; + bool useSample = false; + if (_sampleSteps > 1) { + ++_sampleStep; + if (_sampleStep >= _sampleSteps) { + _sampleStep = 0; + } + else { + useSample = true; + } } updateOutput(useSample, outputs[PHASE7_OUTPUT], _phase7Offset, _phase7Sample, _phase7Active); updateOutput(useSample, outputs[PHASE6_OUTPUT], _phase6Offset, _phase6Sample, _phase6Active); @@ -223,7 +229,7 @@ struct EightFOWidget : ModuleWidget { k->snap = true; k->minAngle = 0.0; k->maxAngle = M_PI; - k->speed = 2.0; + k->speed = 3.0; addParam(w); } addParam(ParamWidget::create<StatefulButton9>(slowParamPosition, module, EightFO::SLOW_PARAM, 0.0, 1.0, 0.0)); diff --git a/src/FMOp.cpp b/src/FMOp.cpp @@ -107,7 +107,7 @@ void FMOp::step() { float offset = 0.0f; if (feedback > 0.001f) { - offset = feedback * _feedbackDelayedSample; + offset = feedback * 2.0f * _feedbackDelayedSample; } if (inputs[FM_INPUT].active) { offset += inputs[FM_INPUT].value * _depth * 2.0f; diff --git a/src/LFO.cpp b/src/LFO.cpp @@ -78,17 +78,21 @@ void LFO::step() { } _phasor.advancePhase(); - bool useSample = true; - ++_sampleStep; - if (_sampleStep >= _sampleSteps) { - _sampleStep = 0; - useSample = false; + bool useSample = false; + if (_sampleSteps > 1) { + ++_sampleStep; + if (_sampleStep >= _sampleSteps) { + _sampleStep = 0; + } + else { + useSample = true; + } } updateOutput(_sine, useSample, false, outputs[SINE_OUTPUT], _sineSample, _sineActive); updateOutput(_triangle, useSample, false, outputs[TRIANGLE_OUTPUT], _triangleSample, _triangleActive); updateOutput(_ramp, useSample, false, outputs[RAMP_UP_OUTPUT], _rampUpSample, _rampUpActive); updateOutput(_ramp, useSample, true, outputs[RAMP_DOWN_OUTPUT], _rampDownSample, _rampDownActive); - updateOutput(_square, useSample, false, outputs[SQUARE_OUTPUT], _squareSample, _squareActive); + updateOutput(_square, false, false, outputs[SQUARE_OUTPUT], _squareSample, _squareActive); } void LFO::updateOutput(Phasor& wave, bool useSample, bool invert, Output& output, float& sample, bool& active) { @@ -97,7 +101,7 @@ void LFO::updateOutput(Phasor& wave, bool useSample, bool invert, Output& output output.value = sample; } else { - sample = wave.nextFromPhasor(_phasor) * amplitude * _scale + _offset; + sample = wave.nextFromPhasor(_phasor) * amplitude * _scale + (invert ? -_offset : _offset); if (invert) { sample = -sample; } diff --git a/src/XCO.cpp b/src/XCO.cpp @@ -70,7 +70,10 @@ void XCO::step() { _sineFeedback *= clamp(inputs[SINE_FEEDBACK_INPUT].value / 10.0f, 0.0f, 1.0f); } - _fmDepth = params[FM_PARAM].value; + _fmDepth = params[FM_DEPTH_PARAM].value; + if (inputs[FM_DEPTH_INPUT].active) { + _fmDepth *= clamp(inputs[FM_DEPTH_INPUT].value / 10.0f, 0.0f, 1.0f); + } _squarePhaseOffset = phaseOffset(params[SQUARE_PHASE_PARAM], inputs[SQUARE_PHASE_INPUT]); _sawPhaseOffset = phaseOffset(params[SAW_PHASE_PARAM], inputs[SAW_PHASE_INPUT]); @@ -170,23 +173,23 @@ void XCO::step() { } if (squareNormal) { - squareOut += mix * amplitude * _squareMix * _square.nextFromPhasor(_phasor, _squarePhaseOffset + phaseOffset); + squareOut += mix * amplitude * _square.nextFromPhasor(_phasor, _squarePhaseOffset + phaseOffset); } if (sawNormal) { - sawOut += mix * amplitude * _sawMix * _saw.nextFromPhasor(_phasor, _sawPhaseOffset + phaseOffset); + sawOut += mix * amplitude * _saw.nextFromPhasor(_phasor, _sawPhaseOffset + phaseOffset); } if (triangleNormal) { - triangleOut += mix * amplitude * _triangleMix * _triangle.nextFromPhasor(_phasor, _trianglePhaseOffset + phaseOffset); + triangleOut += mix * amplitude * _triangle.nextFromPhasor(_phasor, _trianglePhaseOffset + phaseOffset); } if (sineNormal) { - sineOut += amplitude * _sineMix * _sine.nextFromPhasor(_phasor, sineFeedbackOffset + _sinePhaseOffset + phaseOffset); + sineOut += amplitude * _sine.nextFromPhasor(_phasor, sineFeedbackOffset + _sinePhaseOffset + phaseOffset); } outputs[SQUARE_OUTPUT].value = squareOut; outputs[SAW_OUTPUT].value = sawOut; outputs[TRIANGLE_OUTPUT].value = triangleOut; outputs[SINE_OUTPUT].value = _sineFeedbackDelayedSample = sineOut; - outputs[MIX_OUTPUT].value = squareOut + sawOut + triangleOut + sineOut; + outputs[MIX_OUTPUT].value = _squareMix * squareOut + _sawMix * sawOut + _triangleMix * triangleOut + _sineMix * sineOut; } Phasor::phase_delta_t XCO::phaseOffset(Param& param, Input& input) { @@ -246,7 +249,7 @@ struct XCOWidget : ModuleWidget { auto fineParamPosition = Vec(47.0, 153.0); auto slowParamPosition = Vec(121.0, 157.2); auto fmParamPosition = Vec(55.0, 194.0); - auto fmTypeParamPosition = Vec(83.5, 256.5); + auto fmTypeParamPosition = Vec(101.5, 256.5); auto squarePwParamPosition = Vec(147.0, 60.0); auto squarePhaseParamPosition = Vec(147.0, 148.0); auto squareMixParamPosition = Vec(147.0, 237.0); @@ -260,7 +263,8 @@ struct XCOWidget : ModuleWidget { auto sinePhaseParamPosition = Vec(267.0, 148.0); auto sineMixParamPosition = Vec(267.0, 237.0); - auto fmInputPosition = Vec(40.0, 251.0); + auto fmInputPosition = Vec(29.0, 251.0); + auto fmDepthInputPosition = Vec(62.0, 251.0); auto squarePwInputPosition = Vec(143.0, 95.0); auto squarePhaseInputPosition = Vec(143.0, 183.0); auto squareMixInputPosition = Vec(143.0, 272.0); @@ -273,8 +277,8 @@ struct XCOWidget : ModuleWidget { auto sineFeedbackInputPosition = Vec(263.0, 95.0); auto sinePhaseInputPosition = Vec(263.0, 183.0); auto sineMixInputPosition = Vec(263.0, 272.0); - auto pitchInputPosition = Vec(14.0, 318.0); - auto syncInputPosition = Vec(52.0, 318.0); + auto pitchInputPosition = Vec(17.0, 318.0); + auto syncInputPosition = Vec(50.0, 318.0); auto squareOutputPosition = Vec(143.0, 318.0); auto sawOutputPosition = Vec(183.0, 318.0); @@ -288,7 +292,7 @@ struct XCOWidget : ModuleWidget { addParam(ParamWidget::create<Knob68>(frequencyParamPosition, module, XCO::FREQUENCY_PARAM, -3.0, 6.0, 0.0)); addParam(ParamWidget::create<Knob16>(fineParamPosition, module, XCO::FINE_PARAM, -1.0, 1.0, 0.0)); addParam(ParamWidget::create<StatefulButton9>(slowParamPosition, module, XCO::SLOW_PARAM, 0.0, 1.0, 0.0)); - addParam(ParamWidget::create<Knob38>(fmParamPosition, module, XCO::FM_PARAM, 0.0, 1.0, 0.0)); + addParam(ParamWidget::create<Knob38>(fmParamPosition, module, XCO::FM_DEPTH_PARAM, 0.0, 1.0, 0.0)); addParam(ParamWidget::create<SliderSwitch2State14>(fmTypeParamPosition, module, XCO::FM_TYPE_PARAM, 0.0, 1.0, 1.0)); addParam(ParamWidget::create<Knob16>(squarePwParamPosition, module, XCO::SQUARE_PW_PARAM, -0.97, 0.97, 0.0)); addParam(ParamWidget::create<Knob16>(squarePhaseParamPosition, module, XCO::SQUARE_PHASE_PARAM, -1.0, 1.0, 0.0)); @@ -304,6 +308,7 @@ struct XCOWidget : ModuleWidget { addParam(ParamWidget::create<Knob16>(sineMixParamPosition, module, XCO::SINE_MIX_PARAM, 0.0, 1.0, 1.0)); addInput(Port::create<Port24>(fmInputPosition, Port::INPUT, module, XCO::FM_INPUT)); + addInput(Port::create<Port24>(fmDepthInputPosition, Port::INPUT, module, XCO::FM_DEPTH_INPUT)); addInput(Port::create<Port24>(squarePwInputPosition, Port::INPUT, module, XCO::SQUARE_PW_INPUT)); addInput(Port::create<Port24>(squarePhaseInputPosition, Port::INPUT, module, XCO::SQUARE_PHASE_INPUT)); addInput(Port::create<Port24>(squareMixInputPosition, Port::INPUT, module, XCO::SQUARE_MIX_INPUT)); diff --git a/src/XCO.hpp b/src/XCO.hpp @@ -15,7 +15,7 @@ struct XCO : Module { FREQUENCY_PARAM, FINE_PARAM, SLOW_PARAM, - FM_PARAM, + FM_DEPTH_PARAM, FM_TYPE_PARAM, SQUARE_PW_PARAM, SQUARE_PHASE_PARAM, @@ -34,6 +34,7 @@ struct XCO : Module { enum InputsIds { FM_INPUT, + FM_DEPTH_INPUT, SQUARE_PW_INPUT, SQUARE_PHASE_INPUT, SQUARE_MIX_INPUT, diff --git a/src/dsp/oscillator.hpp b/src/dsp/oscillator.hpp @@ -216,8 +216,9 @@ struct BandLimitedSawOscillator : SaturatingSawOscillator { struct SquareOscillator : Phasor { const float minPulseWidth = 0.03f; const float maxPulseWidth = 1.0f - minPulseWidth; + static constexpr float defaultPulseWidth = 0.5f; float _pulseWidthInput; - phase_t _pulseWidth = maxPhase / 2; + phase_t _pulseWidth = maxPhase * defaultPulseWidth; bool positive = true; SquareOscillator(