computerscare-vcv-modules

computerscare modules for VCV Rack
Log | Files | Refs

commit 3b7bf9c967141e807b2b7dad4e59ae5938aec94e
parent 52cb9d091dcc300b79b3f0a04e24ccc67056cfee
Author: Adam M <aemalone@gmail.com>
Date:   Sun, 29 Mar 2020 16:14:45 -0500

Horse poly steps knob and visualz

Diffstat:
Msrc/Computerscare.hpp | 1+
Msrc/ComputerscareHorseADoodleDoo.cpp | 245++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
2 files changed, 163 insertions(+), 83 deletions(-)

diff --git a/src/Computerscare.hpp b/src/Computerscare.hpp @@ -51,6 +51,7 @@ static const NVGcolor COLOR_COMPUTERSCARE_YELLOW = nvgRGB(0xE4, 0xC4, 0x21); static const NVGcolor COLOR_COMPUTERSCARE_BLUE = nvgRGB(0x24, 0x44, 0xC1); static const NVGcolor COLOR_COMPUTERSCARE_PINK = nvgRGB(0xAA, 0x18, 0x31); static const NVGcolor COLOR_COMPUTERSCARE_TRANSPARENT = nvgRGBA(0x00, 0x00, 0x00, 0x00); +static const NVGcolor BLACK=nvgRGB(0x00,0x00,0x00); namespace rack { diff --git a/src/ComputerscareHorseADoodleDoo.cpp b/src/ComputerscareHorseADoodleDoo.cpp @@ -17,7 +17,6 @@ struct HorseSequencer { std::vector<int> absoluteSequence; std::vector<float> cvSequence; - Quantizer quant; HorseSequencer(float patt, int steps, float dens) { numSteps = steps; density = dens; @@ -27,7 +26,7 @@ struct HorseSequencer { void makeAbsolute() { std::vector<int> newSeq; std::vector<float> newCV; - + newSeq.resize(0); newCV.resize(0); /*for (int i = 0; i < 16; i++) { @@ -38,9 +37,9 @@ struct HorseSequencer { newSeq.insert(newSeq.end(), thisOct.begin(), thisOct.end()); //absoluteSequence.push_back(dex < 8 ? 0 : 1); }*/ - quant = Quantizer("3223",12,0); - float cvRange = std::sin(primes[9]*pattern-otherPrimes[3]); + + float cvRange = std::sin(primes[9] * pattern - otherPrimes[3]); int cvRoot = 0;//std::floor(6*(1+std::sin(primes[5]*pattern-otherPrimes[2]))); for (int i = 0; i < numSteps; i++) { @@ -48,11 +47,11 @@ struct HorseSequencer { float cvVal = 0.f; for (int k = 0; k < 4; k++) { val += std::sin(primes[((i + 1) * (k + 1)) % 16] * pattern + otherPrimes[(otherPrimes[0] + i) % 16]); - cvVal+=std::sin(primes[((i + 11) * (k + 1)+201) % 16] * pattern + otherPrimes[(otherPrimes[3] + i-7) % 16]); + cvVal += std::sin(primes[((i + 11) * (k + 1) + 201) % 16] * pattern + otherPrimes[(otherPrimes[3] + i - 7) % 16]); //cvVal+=i/12; } newSeq.push_back(val < (density - 0.5) * 4 * 2 ? 1 : 0); - newCV.push_back(cvRoot+(cvVal+4)/.8); + newCV.push_back(cvRoot + (cvVal + 4) / .8); } printVector(newSeq); absoluteSequence = newSeq; @@ -100,6 +99,7 @@ struct ComputerscareHorseADoodleDoo : Module { DENSITY_TRIM, WEIRDNESS_KNOB, WEIRDNESS_TRIM, + POLY_KNOB, NUM_PARAMS }; @@ -122,8 +122,8 @@ struct ComputerscareHorseADoodleDoo : Module { }; - rack::dsp::SchmittTrigger clockInputTrigger; - rack::dsp::SchmittTrigger resetInputTrigger; + rack::dsp::SchmittTrigger clockInputTrigger[16]; + rack::dsp::SchmittTrigger resetInputTrigger[16]; rack::dsp::SchmittTrigger clockManualTrigger; rack::dsp::SchmittTrigger resetManualTrigger; @@ -131,6 +131,7 @@ struct ComputerscareHorseADoodleDoo : Module { float lastPatternKnob = 0.f; int lastStepsKnob = 2; float lastDensityKnob = 0.f; + int lastPolyKnob=0; float pendingPattern = 0.f; int pendingNumSteps = 8; @@ -157,6 +158,9 @@ struct ComputerscareHorseADoodleDoo : Module { configParam(STEPS_TRIM, -1.f, 1.f, 0.f, "Steps CV Trim"); configParam(DENSITY_TRIM, -1.f, 1.f, 0.f, "Density CV Trim"); + configParam(POLY_KNOB, 0.f, 16.f, 0.f, "Polyphony"); + + seq = HorseSequencer(0.f, 8, 0.f); @@ -181,38 +185,31 @@ struct ComputerscareHorseADoodleDoo : Module { int stepsVal = std::floor(params[STEPS_KNOB].getValue() + params[STEPS_TRIM].getValue() * inputs[STEPS_CV].getVoltage()); float densityVal = params[DENSITY_KNOB].getValue() + params[DENSITY_TRIM].getValue() * inputs[DENSITY_CV].getVoltage() / 10; - if (patternVal != lastPatternKnob || stepsVal != lastStepsKnob || densityVal != lastDensityKnob) { patternKnobChanged(patternVal, stepsVal, densityVal); } lastPatternKnob = patternVal; lastStepsKnob = stepsVal; lastDensityKnob = densityVal; + lastPolyKnob=std::floor(params[POLY_KNOB].getValue()); } - void process(const ProcessArgs &args) override { - counter++; - if (counter > 601) { - checkKnobChanges(); - counter = 0; - } - - bool clockInputHigh = clockInputTrigger.isHigh(); - bool clocked = clockInputTrigger.process(inputs[CLOCK_INPUT].getVoltage()); + void processChannel(int ch) { + bool clockInputHigh = clockInputTrigger[ch].isHigh(); + bool clocked = clockInputTrigger[ch].process(inputs[CLOCK_INPUT].getVoltage()); - bool reset = resetInputTrigger.process(inputs[RESET_INPUT].getVoltage()); + bool reset = resetInputTrigger[ch].process(inputs[RESET_INPUT].getVoltage()); - if(reset) { - if(changePending) { + if (reset) { + if (changePending) { applyChange(); } seq.reset(); - seqVal=seq.get(); - if(seqVal) { - cvVal=seq.getCV(); - } - for (int ch = 0; ch < numChannels; ch++) { - atFirstStepPoly[ch] = true; + seqVal = seq.get(); + if (seqVal) { + cvVal = seq.getCV(); } + atFirstStepPoly[ch] = true; + } @@ -221,11 +218,9 @@ struct ComputerscareHorseADoodleDoo : Module { if (seqVal) { cvVal = seq.getCV(); } + atFirstStepPoly[ch] = (seq.currentStep == 0); - for (int ch = 0; ch < numChannels; ch++) { - atFirstStepPoly[ch] = (seq.currentStep == 0); - } - if (atFirstStepPoly[0] && changePending) { + if (atFirstStepPoly[ch] && changePending) { applyChange(); seqVal = seq.get(); if (seqVal) { @@ -235,51 +230,51 @@ struct ComputerscareHorseADoodleDoo : Module { } if (inputs[CLOCK_INPUT].isConnected()) { - for (int ch = 0; ch < numChannels; ch++) { - outputs[TRIGGER_OUTPUT].setVoltage((clockInputHigh && seqVal == 1) ? 10.0f : 0.0f, ch); - //DEBUG("before output:%f",cvVal); - outputs[CV_OUTPUT].setVoltage(cvVal, ch); - //outputs[EOC_OUTPUT].setVoltage((currentTriggerIsHigh && atFirstStepPoly[ch]) ? 10.f : 0.0f, ch); - } + outputs[TRIGGER_OUTPUT].setVoltage((clockInputHigh && seqVal == 1) ? 10.0f : 0.0f, ch); + //DEBUG("before output:%f",cvVal); + outputs[CV_OUTPUT].setVoltage(cvVal, ch); + //outputs[EOC_OUTPUT].setVoltage((currentTriggerIsHigh && atFirstStepPoly[ch]) ? 10.f : 0.0f, ch); } else { - /* for (int ch = 0; ch < numChannels; ch++) { - outputs[TRG_OUTPUT + i].setVoltage((globalGateIn && activePolyStep[i][ch]) ? 10.0f : 0.0f, ch); - outputs[FIRST_STEP_OUTPUT + i].setVoltage((globalGateIn && atFirstStepPoly[ch]) ? 10.f : 0.0f, ch); - }*/ - } - - - //if (outputs[EOC_OUTPUT].isConnected()) { - for (int ch = 0; ch < numChannels; ch++) { - - if (atFirstStepPoly[ch]) { - - outputs[EOC_OUTPUT].setVoltage((clockInputHigh && atFirstStepPoly[ch]) ? 10.f : 0.0f, ch); - } } - //outputs[EOC_OUTPUT].setVoltage((currentTriggerIsHigh && atFirstStepPoly[ch]) ? 10.f : 0.0f, ch); - //} - - + if (atFirstStepPoly[ch]) { + outputs[EOC_OUTPUT].setVoltage((clockInputHigh && atFirstStepPoly[ch]) ? 10.f : 0.0f, ch); + } } + void process(const ProcessArgs &args) override { + counter++; + if (counter > 601) { + checkKnobChanges(); + counter = 0; + } + processChannel(0); + } }; + struct NumStepsOverKnobDisplay : SmallLetterDisplay { ComputerscareHorseADoodleDoo *module; - NumStepsOverKnobDisplay() + int knobConnection=1; + NumStepsOverKnobDisplay(int type) { - letterSpacing=1.f; + letterSpacing = 1.f; + knobConnection=type; SmallLetterDisplay(); }; void draw(const DrawArgs &args) { if (module) { - std::string str = std::to_string(module->lastStepsKnob); + std::string str=""; + if(knobConnection==1) { + str = std::to_string(module->lastStepsKnob); + } + else if(knobConnection==2){ + str = module->lastPolyKnob == 0 ? "A" :std::to_string(module->lastPolyKnob); + } value = str; } SmallLetterDisplay::draw(args); @@ -292,20 +287,95 @@ struct HorseDisplay : TransparentWidget { HorseDisplay() { } - void drawHorse(const DrawArgs &args, float x=0.f) { + void drawHorse(const DrawArgs &args, float x = 0.f) { + + float dy = 380 / (float)(module->seq.numSteps); + float mid=module->seq.numSteps/2; + + float dh = 0.2;//multiplicitive on original height + float zDistance = 20; + + - float dy=380/(float)(module->seq.numSteps); - for(int i = 0; i<module->seq.numSteps; i++) { + + for (int i = 0; i < module->seq.numSteps; i++) { nvgBeginPath(args.vg); - nvgRect(args.vg, 60,i*dy, 15.f, dy); - nvgFillColor(args.vg, module->seq.absoluteSequence[i] ==1 ? COLOR_COMPUTERSCARE_RED : COLOR_COMPUTERSCARE_TRANSPARENT); - nvgFill(args.vg); - if(i==module->seq.currentStep) { - nvgStrokeWidth(args.vg,3.f); - nvgStrokeColor(args.vg,COLOR_COMPUTERSCARE_BLUE ); + float xx = 65; + float yy = i * dy; + + float ip = i/module->seq.numSteps; + float width = 15.f; + float height = dy; + + if (module->seq.absoluteSequence[i] == 1) { + + float xCloseTop = xx; + float yCloseTop = yy; + float xFarTop = xx - zDistance; + float yFarTop = 100; + float xFarBottom = xFarTop; + float yFarBottom = yFarTop; + float xCloseBottom = xCloseTop; + float yCloseBottom = yCloseTop + height; + + + // left side wall + if (i == module->seq.currentStep) { + nvgFillColor(args.vg, COLOR_COMPUTERSCARE_BLUE ); + } + else { + nvgFillColor(args.vg, COLOR_COMPUTERSCARE_RED); + } + + nvgStrokeColor(args.vg, BLACK); + nvgStrokeWidth(args.vg, .2); + + + nvgBeginPath(args.vg); + nvgMoveTo(args.vg, xCloseTop, yCloseTop); + nvgLineTo(args.vg, xFarTop, yFarTop); + nvgLineTo(args.vg, xFarBottom, yFarBottom); + nvgLineTo(args.vg, xCloseBottom, yCloseBottom); + nvgLineTo(args.vg, xCloseTop, yCloseTop); + nvgClosePath(args.vg); + //nvgRect(args.vg, xx,yy,width,height); + nvgFill(args.vg); + nvgStroke(args.vg); + + + + //top + nvgStrokeWidth(args.vg,1.f); + if (i == module->seq.currentStep) { + nvgFillColor(args.vg, COLOR_COMPUTERSCARE_YELLOW); + } + else { + nvgFillColor(args.vg,nvgRGB(0xE2,0x22,0x12)); + } + nvgBeginPath(args.vg); + nvgRect(args.vg,xx,yy,10.f,dy); + nvgClosePath(args.vg); + //nvgRect(args.vg, xx,yy,width,height); + nvgFill(args.vg); nvgStroke(args.vg); + + + + + //nvgRestore(args.vg); + + //nvgReset(args.vg); + + + + } + else { + //nvgFillColor(args.vg,COLOR_COMPUTERSCARE_TRANSPARENT); } + //nvgFillColor(args.vg, module->seq.absoluteSequence[i] == 1 ? COLOR_COMPUTERSCARE_RED : COLOR_COMPUTERSCARE_TRANSPARENT); + + } } @@ -339,12 +409,14 @@ struct ComputerscareHorseADoodleDooWidget : ModuleWidget { addInputBlock("Length", 0, 150, module, 2, ComputerscareHorseADoodleDoo::STEPS_CV, 1); addInputBlock("Density", 0, 200, module, 4, ComputerscareHorseADoodleDoo::DENSITY_CV, 0); + addInputBlock("Polyphony", 0, 240, module, ComputerscareHorseADoodleDoo::POLY_KNOB, -1, 2); + horseDisplay = new HorseDisplay(); - horseDisplay->module=module; + horseDisplay->module = module; addChild(horseDisplay); - int outputY = 254; + int outputY = 269; int dy = 30; int outputX = 32; @@ -373,12 +445,16 @@ struct ComputerscareHorseADoodleDooWidget : ModuleWidget { smallLetterDisplay->fontSize = 21; smallLetterDisplay->value = label; smallLetterDisplay->textAlign = 1; - if (knobType == 0) { + + + if (knobType == 0) {//smooth addParam(createParam<SmoothKnob>(Vec(x, y), module, knobIndex)); + //trim knob + addParam(createParam<SmallKnob>(Vec(x + 30, y), module, knobIndex + 1)); + addInput(createInput<TinyJack>(Vec(x + 40, y), module, inputIndex)); } - else if (knobType == 1) { - - numStepsKnob = new NumStepsOverKnobDisplay(); + else if (knobType == 1 || knobType == 2) { + numStepsKnob = new NumStepsOverKnobDisplay(knobType); numStepsKnob->box.size = Vec(20, 20); numStepsKnob->box.pos = Vec(x - 2.5 , y + 1.f); numStepsKnob->fontSize = 26; @@ -388,22 +464,25 @@ struct ComputerscareHorseADoodleDooWidget : ModuleWidget { numStepsKnob->module = module; addParam(createParam<MediumDotSnapKnob>(Vec(x, y), module, knobIndex)); addChild(numStepsKnob); + if (knobType == 1) { + //trim knob + addParam(createParam<SmallKnob>(Vec(x + 30, y), module, knobIndex + 1)); + addInput(createInput<TinyJack>(Vec(x + 40, y), module, inputIndex)); + } } + - //trim knob - addParam(createParam<SmallKnob>(Vec(x + 30, y), module, knobIndex + 1)); - addInput(createInput<TinyJack>(Vec(x + 40, y), module, inputIndex)); - smallLetterDisplay->box.pos = Vec(x, y - 12); + smallLetterDisplay->box.pos = Vec(x, y - 12); - addChild(smallLetterDisplay); + addChild(smallLetterDisplay); - } - HorseDisplay* horseDisplay; - NumStepsOverKnobDisplay* numStepsKnob; - InputBlockBackground* background; - SmallLetterDisplay* smallLetterDisplay; +} +HorseDisplay* horseDisplay; +NumStepsOverKnobDisplay* numStepsKnob; +InputBlockBackground* background; +SmallLetterDisplay* smallLetterDisplay; }; Model *modelComputerscareHorseADoodleDoo = createModel<ComputerscareHorseADoodleDoo, ComputerscareHorseADoodleDooWidget>("computerscare-horse-a-doodle-doo");