computerscare-vcv-modules

computerscare modules for VCV Rack
Log | Files | Refs

commit d12a0e021d65a1e52d22a2ee6e1bd74eea488d6a
parent 87ed4d4d59169a82e2593970af5e79ce4187c3d5
Author: Adam M <aemalone@gmail.com>
Date:   Fri, 19 Nov 2021 08:27:14 -0600

horse-a-doodle-doo add gate length offset,scale and phase menu params

Diffstat:
Msrc/ComputerscareHorseADoodleDoo.cpp | 82++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 58 insertions(+), 24 deletions(-)

diff --git a/src/ComputerscareHorseADoodleDoo.cpp b/src/ComputerscareHorseADoodleDoo.cpp @@ -40,6 +40,7 @@ struct HorseSequencer { int pendingNumSteps = 8; float pendingDensity = 0.5f; float pendingPhase = 0.f; + float pendingGatePhase = 0.f; bool pendingChange = 0; bool forceChange = 0; @@ -60,12 +61,13 @@ struct HorseSequencer { HorseSequencer() { } - HorseSequencer(float patt, int steps, float dens, int ch, float phi) { + HorseSequencer(float patt, int steps, float dens, int ch, float phi, float gatePhi) { numSteps = steps; density = dens; pattern = patt; channel = ch; phase = phi; + gatePhase = gatePhi; makeAbsolute(); } void makeAbsolute() { @@ -115,6 +117,8 @@ struct HorseSequencer { newSeq.push_back(val < (density - 0.5) * 4 * 2 ? 1 : 0); newCV.push_back(cvRoot + (cvVal + 4) / .8); newCV2.push_back(cv2Root + (cv2Val + 4) / .8); + + //quantized to 16 lengths newGateLength.push_back(std::floor(8 + 2 * gateLengthVal)); } //printVector(newSeq); @@ -125,13 +129,14 @@ struct HorseSequencer { setTimeToNextStep(); } - void checkAndArm(float patt, int steps, float dens, float phi) { + void checkAndArm(float patt, int steps, float dens, float phi, float gatePhi) { - if (pattern != patt || numSteps != steps || density != dens || phase != phi) { + if (pattern != patt || numSteps != steps || density != dens || phase != phi || gatePhase != gatePhi) { pendingPattern = patt; pendingNumSteps = steps; pendingDensity = dens; pendingPhase = phi; + pendingGatePhase = gatePhi; pendingChange = true; } } @@ -144,12 +149,14 @@ struct HorseSequencer { pendingNumSteps = numSteps; pendingDensity = density; pendingPhase = phase; + pendingGatePhase = gatePhase; } - void change(float patt, int steps, float dens, float phi) { + void change(float patt, int steps, float dens, float phi, float gatePhi) { numSteps = std::max(1, steps); density = std::fmax(0, dens); pattern = patt; phase = phi; + gatePhase = gatePhi; currentStep = 0; makeAbsolute(); @@ -158,7 +165,7 @@ struct HorseSequencer { currentStep++; currentStep %= numSteps; if ((currentStep == 0 && pendingChange) || forceChange) { - change(pendingPattern, pendingNumSteps, pendingDensity, pendingPhase); + change(pendingPattern, pendingNumSteps, pendingDensity, pendingPhase, pendingGatePhase); pendingChange = false; forceChange = false; currentStep = 0; @@ -236,6 +243,9 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { CV_OFFSET, CV_PHASE, GATE_MODE, + GATE_LENGTH_SCALE, + GATE_LENGTH_OFFSET, + GATE_LENGTH_PHASE, NUM_PARAMS }; enum InputIds { @@ -256,7 +266,6 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { NUM_LIGHTS }; - rack::dsp::SchmittTrigger clockInputTrigger[16]; rack::dsp::SchmittTrigger resetInputTrigger[16]; @@ -267,19 +276,22 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { dsp::PulseGenerator gatePulse[16]; - - float lastPatternKnob = 0.f; int lastStepsKnob = 2; float lastDensityKnob = 0.f; int lastPolyKnob = 0; float lastPhaseKnob = 0.f; + float lastGatePhaseKnob = 0.f; float cvOffset = 0.f; float cvScale = 1.f; + float gateLengthOffset = 0.f; + float gateLengthScale = 1.f; + int mode = 1; + int gateMode = 1; int seqVal[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; float cvVal[16] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; @@ -370,7 +382,7 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { configParam<HorseModeParam>(MODE_KNOB, 0.f, 3.f, 0.f, "Mode"); - configParam<HorseModeParam>(GATE_MODE, 0.f, 2.f, 0.f, "Gate Mode"); + configParam<HorseModeParam>(GATE_MODE, 0.f, 1.f, 1.f, "Gate Mode"); configParam<HorseResetParamQ>(MANUAL_RESET_BUTTON, 0.f, 1.f, 0.f, "Reset all Sequences"); configParam(MANUAL_CLOCK_BUTTON, 0.f, 1.f, 0.f, "Advance all Sequences"); @@ -379,6 +391,10 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { configMenuParam(CV_OFFSET, -10.f, 10.f, 0.f, "CV Offset", 2); configMenuParam(CV_PHASE, -3.14159f, 3.14159f, 0.f, "CV Phase", 2); + configMenuParam(GATE_LENGTH_SCALE, 0.f, 2.f, 1.f, "Gate Length Scale", 2); + configMenuParam(GATE_LENGTH_OFFSET, 0.f, 1.f, 0.f, "Gate Length Offset", 2); + configMenuParam(GATE_LENGTH_PHASE, -3.14159f, 3.14159f, 0.f, "Gate Length Phase", 2); + getParamQuantity(POLY_KNOB)->randomizeEnabled = false; getParamQuantity(MODE_KNOB)->randomizeEnabled = false; @@ -398,7 +414,7 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { configOutput(CV_OUTPUT, "CV Sequence"); for (int i = 0; i < 16; i++) { - seq[i] = HorseSequencer(0.f, 8, 0.f, i, 0.f); + seq[i] = HorseSequencer(0.f, 8, 0.f, i, 0.f, 0.f); previousStep[i] = -1; } @@ -501,6 +517,7 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { } void setGateMode(int newGateMode) { params[GATE_MODE].setValue(newGateMode); + gateMode = newGateMode; } void checkKnobChanges() { @@ -515,11 +532,15 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { cvScale = params[CV_SCALE].getValue(); cvOffset = params[CV_OFFSET].getValue(); + gateLengthOffset = params[GATE_LENGTH_OFFSET].getValue(); + gateLengthScale = params[GATE_LENGTH_SCALE].getValue(); + mode = params[MODE_KNOB].getValue(); lastStepsKnob = std::floor(params[STEPS_KNOB].getValue()); lastPolyKnob = std::floor(params[POLY_KNOB].getValue()); lastPhaseKnob = params[CV_PHASE].getValue(); + lastGatePhaseKnob = params[GATE_LENGTH_PHASE].getValue(); polyChannels = lastPolyKnob == 0 ? std::max(clockNum, std::max(pattNum, std::max(stepsNum, densityNum))) : lastPolyKnob; @@ -544,7 +565,7 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { stepsVal = std::max(2, stepsVal); densityVal = std::fmax(0, std::fmin(1, densityVal)); - seq[i].checkAndArm(patternVal, stepsVal, densityVal, lastPhaseKnob); + seq[i].checkAndArm(patternVal, stepsVal, densityVal, lastPhaseKnob, lastGatePhaseKnob); } } void processChannel(int ch, bool clocked, bool reset, bool clockInputHigh, int overrideMode = 0, bool overriddenTriggerHigh = false) { @@ -586,15 +607,18 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { previousStep[ch] = seq[ch].currentStep; - int len = seq[ch].getGateLength(); - int ttns = seq[ch].getTimeToNextStep(); - if (ch == 0 || ch == 1) { - DEBUG("ch:%i,step:%i,len:%i,ttns:%i", ch, seq[ch].currentStep, len, ttns); - } - if (true && shouldOutputPulse[ch]) { + if (gateMode == 1 && shouldOutputPulse[ch]) { + int len = seq[ch].getGateLength(); + int ttns = seq[ch].getTimeToNextStep(); + float timeLeft = syncTime[0] * ttns; + float gateLengthFactor = math::clamp(gateLengthOffset + gateLengthScale * ((float)len) / 16, 0.05f, 0.95f); + float ms = timeLeft * gateLengthFactor; + if (ch == 0 || ch == 1) { + //DEBUG("ch:%i,step:%i,len:%i,ttns:%i,ms:%f", ch, seq[ch].currentStep, len, ttns, ms); + } + gatePulse[ch].reset(); - // gatePulse[ch].trigger(syncTime[0] * ttns * (len > 4 ? .7 : 0.01)); - gatePulse[ch].trigger(syncTime[0] * ttns * ((float)len) / 16); + gatePulse[ch].trigger(ms); } @@ -602,12 +626,12 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { if (true || inputs[CLOCK_INPUT].isConnected()) { - if (false) { - //trigger pass-through mode + if (gateMode == 0) { + //clock pass-through mode outputs[TRIGGER_OUTPUT].setVoltage((clockInputHigh && shouldOutputPulse[ch]) ? 10.0f : 0.0f, ch); } - else { + else if (gateMode == 1) { //gate mode bool gateHigh = gatePulse[ch].process(APP->engine->getSampleTime()); @@ -652,8 +676,6 @@ struct ComputerscareHorseADoodleDoo : ComputerscareMenuParamModule { } } - - if (mode == 0) { //each poly channel processes independent trigger and cv for (int i = 0; i < 16; i++) { @@ -936,6 +958,18 @@ struct ComputerscareHorseADoodleDooWidget : ModuleWidget { MenuParam* cvPhaseParamControl = new MenuParam(horse->paramQuantities[ComputerscareHorseADoodleDoo::CV_PHASE], 2); menu->addChild(cvPhaseParamControl); + + menu->addChild(construct<MenuLabel>(&MenuLabel::text, "")); + menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Gate Length Options")); + + MenuParam* gateScaleParamControl = new MenuParam(horse->paramQuantities[ComputerscareHorseADoodleDoo::GATE_LENGTH_SCALE], 2); + menu->addChild(gateScaleParamControl); + + MenuParam* gateOffsetParamControl = new MenuParam(horse->paramQuantities[ComputerscareHorseADoodleDoo::GATE_LENGTH_OFFSET], 2); + menu->addChild(gateOffsetParamControl); + + MenuParam* gatePhaseParamControl = new MenuParam(horse->paramQuantities[ComputerscareHorseADoodleDoo::GATE_LENGTH_PHASE], 2); + menu->addChild(gatePhaseParamControl); } PolyOutputChannelsWidget* channelWidget; NumStepsOverKnobDisplay* numStepsKnob;