computerscare-vcv-modules

computerscare modules for VCV Rack
Log | Files | Refs

commit 73c40c16e95bfde2d793e2ef925ff37dc570128d
parent 75743032ab94192529a74c2334e78e8dae6aadce
Author: Adam M <[email protected]>
Date:   Tue, 12 Mar 2019 22:45:57 -0500

Change slugs back to v0.6 version, upgrade Oh Peas to v1

Diffstat:
MMakefile | 2++
Mplugin.json | 9+++++++--
Msrc/Computerscare.cpp | 3++-
Msrc/Computerscare.hpp | 5+++--
Msrc/ComputerscareDebug.cpp | 28++++++++++++++--------------
Msrc/ComputerscareILoveCookies.cpp | 92++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/ComputerscareIso.cpp | 2+-
Msrc/ComputerscareKnolyPobs.cpp | 4++--
Msrc/ComputerscareLaundrySoup.cpp | 66++++++++++++++++++++++++++++++++++--------------------------------
Msrc/ComputerscareOhPeas.cpp | 369++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/ComputerscarePatchSequencer.cpp | 78++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/dtpulse.cpp | 3+++
12 files changed, 387 insertions(+), 274 deletions(-)

diff --git a/Makefile b/Makefile @@ -19,8 +19,10 @@ SOURCES += $(wildcard src/ComputerscareIso.cpp) SOURCES += $(wildcard src/ComputerscareKnolyPobs.cpp) SOURCES += $(wildcard src/ComputerscareDebug.cpp) +SOURCES += $(wildcard src/ComputerscareOhPeas.cpp) SOURCES += $(wildcard src/Computerscare.cpp) +SOURCES += $(wildcard src/dtpulse.cpp) # Add files to the ZIP package when running `make dist` # The compiled plugin is automatically added. diff --git a/plugin.json b/plugin.json @@ -14,15 +14,20 @@ "description": "Isopig testing", "tags": ["Poly","Utility"] }, - "KnolyPobs":{ + "computerscare-knolypobs":{ "name":"Knoly pobs", "description":"Poly Knobs, 16 of them", "tags":["Poly","Utility"] }, - "Debug":{ + "computerscare-debug":{ "name":"Debug", "description":"Debugger", "tags":["Poly","Utility"] + }, + "computerscare-ohpeas":{ + "name":"Oh Peas!", + "description":"Quad Quantenuverter. Attenuverter, Offsetter, Microtonal Quantizer", + "tags":["Poly"] } } } \ No newline at end of file diff --git a/src/Computerscare.cpp b/src/Computerscare.cpp @@ -7,10 +7,11 @@ void init(Plugin *p) { pluginInstance = p; p->addModel(modelComputerscareDebug); + //p->addModel(modelComputerscarePatchSequencer); //p->addModel(modelComputerscareLaundrySoup); //p->addModel(modelComputerscareILoveCookies); - //p->addModel(modelComputerscareOhPeas); + p->addModel(modelComputerscareOhPeas); p->addModel(modelComputerscareIso); p->addModel(modelComputerscareKnolyPobs); } diff --git a/src/Computerscare.hpp b/src/Computerscare.hpp @@ -25,10 +25,11 @@ extern Plugin *pluginInstance; // Forward-declare each Model, defined in each module source file extern Model *modelComputerscareDebug; + //extern Model *modelComputerscarePatchSequencer; //extern Model *modelComputerscareLaundrySoup; //extern Model *modelComputerscareILoveCookies; -//extern Model *modelComputerscareOhPeas; +extern Model *modelComputerscareOhPeas; extern Model *modelComputerscareIso; extern Model *modelComputerscareKnolyPobs; @@ -245,7 +246,7 @@ struct ComputerscareDotKnob : SmallKnob { //////////////////////////////////// -struct SmallLetterDisplay : TransparentWidget { +struct SmallLetterDisplay : Widget { std::string value; std::shared_ptr<Font> font; diff --git a/src/ComputerscareDebug.cpp b/src/ComputerscareDebug.cpp @@ -71,11 +71,11 @@ struct ComputerscareDebug : Module { params[INPUT_CHANNEL_FOCUS].config(0.f,15.f,0.f,"Input Channel Selector"); outputs[POLY_OUTPUT].setChannels(16); - params[MANUAL_TRIGGER].randomizable=false; - params[MANUAL_CLEAR_TRIGGER].randomizable=false; + //params[MANUAL_TRIGGER].randomizable=false; + //params[MANUAL_CLEAR_TRIGGER].randomizable=false; } - void step() override; + void process(const ProcessArgs &args) override; // For more advanced Module features, read Rack's engine.hpp header file // - toJson, fromJson: serialization of internal data @@ -86,17 +86,17 @@ struct ComputerscareDebug : Module { }; -void ComputerscareDebug::step() { +void ComputerscareDebug::process(const ProcessArgs &args) { std::string thisVal; - clockMode = floor(params[WHICH_CLOCK].value); + clockMode = floor(params[WHICH_CLOCK].getValue()); - inputMode = floor(params[SWITCH_VIEW].value); + inputMode = floor(params[SWITCH_VIEW].getValue()); - inputChannel = floor(params[INPUT_CHANNEL_FOCUS].value); - clockChannel = floor(params[CLOCK_CHANNEL_FOCUS].value); + inputChannel = floor(params[INPUT_CHANNEL_FOCUS].getValue()); + clockChannel = floor(params[CLOCK_CHANNEL_FOCUS].getValue()); if(clockMode == SINGLE_MODE) { - if (clockTriggers[clockChannel].process(inputs[TRG_INPUT].getVoltage(clockChannel) / 2.f) || manualClockTrigger.process(params[MANUAL_TRIGGER].value) ) { + if (clockTriggers[clockChannel].process(inputs[TRG_INPUT].getVoltage(clockChannel) / 2.f) || manualClockTrigger.process(params[MANUAL_TRIGGER].getValue()) ) { if(inputMode == POLY_MODE) { for(int i = 0; i < 16; i++) { logLines[i] = inputs[VAL_INPUT].getVoltage(i); @@ -140,28 +140,28 @@ void ComputerscareDebug::step() { else if(clockMode == POLY_MODE) { if(inputMode == POLY_MODE) { for(int i = 0; i < 16; i++) { - if (clockTriggers[i].process(inputs[TRG_INPUT].getVoltage(i) / 2.f) || manualClockTrigger.process(params[MANUAL_TRIGGER].value) ) { + if (clockTriggers[i].process(inputs[TRG_INPUT].getVoltage(i) / 2.f) || manualClockTrigger.process(params[MANUAL_TRIGGER].getValue()) ) { logLines[i] = inputs[VAL_INPUT].getVoltage(i); } } } else if(inputMode == SINGLE_MODE) { for(int i = 0; i < 16; i++) { - if (clockTriggers[i].process(inputs[TRG_INPUT].getVoltage(i) / 2.f) || manualClockTrigger.process(params[MANUAL_TRIGGER].value) ) { + if (clockTriggers[i].process(inputs[TRG_INPUT].getVoltage(i) / 2.f) || manualClockTrigger.process(params[MANUAL_TRIGGER].getValue()) ) { logLines[i] = inputs[VAL_INPUT].getVoltage(inputChannel); } } } else if(inputMode == INTERNAL_MODE) { for(int i = 0; i < 16; i++) { - if (clockTriggers[i].process(inputs[TRG_INPUT].getVoltage(i) / 2.f) || manualClockTrigger.process(params[MANUAL_TRIGGER].value) ) { + if (clockTriggers[i].process(inputs[TRG_INPUT].getVoltage(i) / 2.f) || manualClockTrigger.process(params[MANUAL_TRIGGER].getValue()) ) { logLines[i] = random::uniform(); } } } } - if(clearTrigger.process(inputs[CLR_INPUT].getVoltage() / 2.f) || manualClearTrigger.process(params[MANUAL_CLEAR_TRIGGER].value)) { + if(clearTrigger.process(inputs[CLR_INPUT].getVoltage() / 2.f) || manualClearTrigger.process(params[MANUAL_CLEAR_TRIGGER].getValue())) { for( unsigned int a = 0; a < NUM_LINES; a++ ) { logLines[a] = 0; @@ -319,4 +319,4 @@ struct ComputerscareDebugWidget : ModuleWidget { }; -Model *modelComputerscareDebug = createModel<ComputerscareDebug, ComputerscareDebugWidget>("Debug"); +Model *modelComputerscareDebug = createModel<ComputerscareDebug, ComputerscareDebugWidget>("computerscare-debug"); diff --git a/src/ComputerscareILoveCookies.cpp b/src/ComputerscareILoveCookies.cpp @@ -44,20 +44,20 @@ public: bndSetFont(gGuiFont->handle); return textPos; } - void draw(NVGcontext *vg) override { - nvgScissor(vg, 0, 0, box.size.x, box.size.y); + void draw(const DrawArgs &args) override { + nvgScissor(args.vg, 0, 0, box.size.x, box.size.y); // Background - nvgFontSize(vg, fontSize); - nvgBeginPath(vg); - nvgRoundedRect(vg, 0, 0, box.size.x, box.size.y, 5.0); + nvgFontSize(args.vg, fontSize); + nvgBeginPath(args.vg); + nvgRoundedRect(args.vg, 0, 0, box.size.x, box.size.y, 5.0); if(inError) { - nvgFillColor(vg, COLOR_COMPUTERSCARE_PINK); + nvgFillColor(args.vg, COLOR_COMPUTERSCARE_PINK); } else { - nvgFillColor(vg, nvgRGB(0x00, 0x00, 0x00)); + nvgFillColor(args.vg, nvgRGB(0x00, 0x00, 0x00)); } - nvgFill(vg); + nvgFill(args.vg); // Text if (font->handle >= 0) { @@ -67,15 +67,15 @@ public: highlightColor.a = 0.5; int begin = min(cursor, selection); int end = (this == gFocusedWidget) ? max(cursor, selection) : -1; - //bndTextField(vg,textOffset.x,textOffset.y+2, box.size.x, box.size.y, -1, 0, 0, const char *text, int cbegin, int cend); - bndIconLabelCaret(vg, textOffset.x, textOffset.y - 3, + //bndTextField(args.vg,textOffset.x,textOffset.y+2, box.size.x, box.size.y, -1, 0, 0, const char *text, int cbegin, int cend); + bndIconLabelCaret(args.vg, textOffset.x, textOffset.y - 3, box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, -1, color, fontSize, text.c_str(), highlightColor, begin, end); bndSetFont(gGuiFont->handle); } - nvgResetScissor(vg); + nvgResetScissor(args.vg); }; private: @@ -133,8 +133,9 @@ struct ComputerscareILoveCookies : Module { std::vector<ParamWidget*> smallLetterKnobs; -ComputerscareILoveCookies() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; +ComputerscareILoveCookies() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);} + void process(const ProcessArgs &args) override; json_t *toJson() override { @@ -170,11 +171,11 @@ ComputerscareILoveCookies() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LI } void wiggleKnobs() { for(int i = 0; i < numKnobs; i++) { - float prev = params[KNOB_PARAM+i].value; - if(randomUniform() < 0.7) { - float rv = (10*randomUniform()+2*prev)/3; + float prev = params[KNOB_PARAM+i].getValue(); + if(random::uniform() < 0.7) { + float rv = (10*random::uniform()+2*prev)/3; this->smallLetterKnobs[i]->setValue(rv); - params[KNOB_PARAM+i].value = rv; + params[KNOB_PARAM+i].getValue() = rv; } } } @@ -187,12 +188,12 @@ ComputerscareILoveCookies() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LI int length = 0; for (int i = 0; i < numFields; i++) { - length = floor(randomUniform()*12) + 2; + length = floor(random::uniform()*12) + 2; str = ""; for(int j = 0; j < length; j++) { - randchar = mainlookup[floor(randomUniform()*mainlookup.size())]; + randchar = mainlookup[floor(random::uniform()*mainlookup.size())]; str = str + randchar; - ru = randomUniform(); + ru = random::uniform(); if(ru < 0.1) { str = "(" + str + ")"; } @@ -300,40 +301,40 @@ void onCreate () override }; -void ComputerscareILoveCookies::step() { +void ComputerscareILoveCookies::process(const ProcessArgs &args) { bool globalGateIn = globalClockTrigger.isHigh(); bool activeStep = 0; bool atFirstStep = false; - bool globalTriggerClocked = globalClockTrigger.process(inputs[GLOBAL_CLOCK_INPUT].value); - bool globalManualResetClicked = globalManualResetTrigger.process(params[MANUAL_RESET_PARAM].value); - bool globalManualClockClicked = globalManualClockTrigger.process(params[MANUAL_CLOCK_PARAM].value); + bool globalTriggerClocked = globalClockTrigger.process(inputs[GLOBAL_CLOCK_INPUT].getVoltage()); + bool globalManualResetClicked = globalManualResetTrigger.process(params[MANUAL_RESET_PARAM].getValue()); + bool globalManualClockClicked = globalManualClockTrigger.process(params[MANUAL_CLOCK_PARAM].getValue()); bool currentTriggerIsHigh; bool currentTriggerClocked; - bool globalResetTriggered = globalResetTriggerInput.process(inputs[GLOBAL_RESET_INPUT].value / 2.f); + bool globalResetTriggered = globalResetTriggerInput.process(inputs[GLOBAL_RESET_INPUT].getVoltage() / 2.f); bool currentResetActive; bool currentResetTriggered; bool currentManualResetClicked; float knobRawValue = 0.f; for(int i = 0; i < numFields; i++) { activeStep = false; - currentResetActive = inputs[RESET_INPUT + i].active; - currentResetTriggered = resetTriggers[i].process(inputs[RESET_INPUT+i].value / 2.f); - currentManualResetClicked = manualResetTriggers[i].process(params[INDIVIDUAL_RESET_PARAM + i].value); + currentResetActive = inputs[RESET_INPUT + i].isConnected(); + currentResetTriggered = resetTriggers[i].process(inputs[RESET_INPUT+i].getVoltage() / 2.f); + currentManualResetClicked = manualResetTriggers[i].process(params[INDIVIDUAL_RESET_PARAM + i].getValue()); currentTriggerIsHigh = clockTriggers[i].isHigh(); - currentTriggerClocked = clockTriggers[i].process(inputs[CLOCK_INPUT + i].value); + currentTriggerClocked = clockTriggers[i].process(inputs[CLOCK_INPUT + i].getVoltage()); if(true) { - if (inputs[CLOCK_INPUT + i].active) { + if (inputs[CLOCK_INPUT + i].isConnected()) { if(currentTriggerClocked) { incrementInternalStep(i); activeKnobIndex[i] = newABS[i].peekWorkingStep(); } } else { - if ((inputs[GLOBAL_CLOCK_INPUT].active && globalTriggerClocked) || globalManualClockClicked) { + if ((inputs[GLOBAL_CLOCK_INPUT].isConnected() && globalTriggerClocked) || globalManualClockClicked) { incrementInternalStep(i); activeKnobIndex[i] = newABS[i].peekWorkingStep(); } @@ -353,36 +354,36 @@ void ComputerscareILoveCookies::step() { setChangeImminent(i,false); } else { - if(atFirstStep && !currentResetActive && !inputs[GLOBAL_RESET_INPUT].active) { + if(atFirstStep && !currentResetActive && !inputs[GLOBAL_RESET_INPUT].isConnected()) { //checkIfShouldChange(i); } } } if(activeKnobIndex[i] < 0) { - outputs[TRG_OUTPUT + i].value = 0.f; + outputs[TRG_OUTPUT + i].setVoltage(0.f); } else if(activeKnobIndex[i] < 26) { - knobRawValue = params[activeKnobIndex[i]].value; - outputs[TRG_OUTPUT + i].value = mapKnobValue(knobRawValue,i); + knobRawValue = params[activeKnobIndex[i]].getValue(); + outputs[TRG_OUTPUT + i].setVoltage(mapKnobValue(knobRawValue,i)); } else if(activeKnobIndex[i] < 52) { - knobRawValue = inputs[SIGNAL_INPUT + activeKnobIndex[i] - 26].value; - outputs[TRG_OUTPUT + i].value = knobRawValue; + knobRawValue = inputs[SIGNAL_INPUT + activeKnobIndex[i] - 26].getVoltage(); + outputs[TRG_OUTPUT + i].setVoltage(knobRawValue); } else if(activeKnobIndex[i] < 78) { - outputs[TRG_OUTPUT + i].value = newABS[i].exactFloats[activeKnobIndex[i] - 52]; + outputs[TRG_OUTPUT + i].setVoltage(newABS[i].exactFloats[activeKnobIndex[i] - 52]); } else if(activeKnobIndex[i] < 104) { - outputs[TRG_OUTPUT + i].value = 2.22; + outputs[TRG_OUTPUT + i].setVoltage(2.22); } else { - outputs[TRG_OUTPUT+i].value = 0.f; + outputs[TRG_OUTPUT+i].setVoltage(0.f); } - if(inputs[CLOCK_INPUT + i].active) { - outputs[FIRST_STEP_OUTPUT + i].value = (currentTriggerIsHigh && atFirstStep) ? 10.f : 0.0f; + if(inputs[CLOCK_INPUT + i].isConnected()) { + outputs[FIRST_STEP_OUTPUT + i].setVoltage((currentTriggerIsHigh && atFirstStep) ? 10.f : 0.0f); } else { - outputs[FIRST_STEP_OUTPUT + i].value = (globalGateIn && atFirstStep) ? 10.f : 0.0f; + outputs[FIRST_STEP_OUTPUT + i].setVoltage((globalGateIn && atFirstStep) ? 10.f : 0.0f); } } } @@ -437,8 +438,9 @@ struct ComputerscareILoveCookiesWidget : ModuleWidget { double inputRowWidth = 9.4; double inputColumnHeight = 9.7; - ComputerscareILoveCookiesWidget(ComputerscareILoveCookies *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/ComputerscareILoveCookiesPanel.svg"))); + ComputerscareILoveCookiesWidget(ComputerscareILoveCookies *module) { + setModule(module); + setPanel(APP->window->loadSvg(asset::plugin(plugin, "res/ComputerscareILoveCookiesPanel.svg"))); for(int i = 0; i < numKnobRows; i++) { for(int j = 0; j < numKnobColumns; j++) { diff --git a/src/ComputerscareIso.cpp b/src/ComputerscareIso.cpp @@ -40,7 +40,7 @@ struct ComputerscareIso : Module { params[TOGGLES].config(0.0f, 1.0f, 0.0f); outputs[POLY_OUTPUT].setChannels(16); } - void step() override { + void process(const ProcessArgs &args) override { counter++; if(counter > 5012) { //printf("%f \n",random::uniform()); diff --git a/src/ComputerscareKnolyPobs.cpp b/src/ComputerscareKnolyPobs.cpp @@ -40,7 +40,7 @@ struct ComputerscareKnolyPobs : Module { params[TOGGLES].config(0.0f, 1.0f, 0.0f); outputs[POLY_OUTPUT].setChannels(16); } - void step() override { + void process(const ProcessArgs &args) override { counter++; if(counter > 5012) { //printf("%f \n",random::uniform()); @@ -122,4 +122,4 @@ void addLabeledKnob(std::string label,int x, int y, ComputerscareKnolyPobs *modu SmallLetterDisplay* smallLetterDisplay; }; -Model *modelComputerscareKnolyPobs = createModel<ComputerscareKnolyPobs, ComputerscareKnolyPobsWidget>("KnolyPobs"); +Model *modelComputerscareKnolyPobs = createModel<ComputerscareKnolyPobs, ComputerscareKnolyPobsWidget>("computerscare-knolypobs"); diff --git a/src/ComputerscareLaundrySoup.cpp b/src/ComputerscareLaundrySoup.cpp @@ -31,21 +31,21 @@ public: bndSetFont(gGuiFont->handle); return textPos; } - void draw(NVGcontext *vg) override { - nvgScissor(vg, 0, 0, box.size.x, box.size.y); + void draw(const DrawArgs &args) override { + nvgScissor(args.vg, 0, 0, box.size.x, box.size.y); // Background - nvgFontSize(vg, fontSize); - nvgBeginPath(vg); - nvgRoundedRect(vg, 0, 0, box.size.x, box.size.y, 10.0); + nvgFontSize(args.vg, fontSize); + nvgBeginPath(args.vg); + nvgRoundedRect(args.vg, 0, 0, box.size.x, box.size.y, 10.0); if(inError) { - nvgFillColor(vg, COLOR_COMPUTERSCARE_PINK); + nvgFillColor(args.vg, COLOR_COMPUTERSCARE_PINK); } else { - nvgFillColor(vg, nvgRGB(0x00, 0x00, 0x00)); + nvgFillColor(args.vg, nvgRGB(0x00, 0x00, 0x00)); } - nvgFill(vg); + nvgFill(args.vg); // Text if (font->handle >= 0) { @@ -55,15 +55,15 @@ public: highlightColor.a = 0.5; int begin = min(cursor, selection); int end = (this == gFocusedWidget) ? max(cursor, selection) : -1; - //bndTextField(vg,textOffset.x,textOffset.y+2, box.size.x, box.size.y, -1, 0, 0, const char *text, int cbegin, int cend); - bndIconLabelCaret(vg, textOffset.x, textOffset.y - 3, + //bndTextField(args.vg,textOffset.x,textOffset.y+2, box.size.x, box.size.y, -1, 0, 0, const char *text, int cbegin, int cend); + bndIconLabelCaret(args.vg, textOffset.x, textOffset.y - 3, box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, -1, color, fontSize, text.c_str(), highlightColor, begin, end); bndSetFont(gGuiFont->handle); } - nvgResetScissor(vg); + nvgResetScissor(args.vg); }; private: @@ -114,8 +114,9 @@ struct ComputerscareLaundrySoup : Module { bool shouldChange[numFields] = {false}; -ComputerscareLaundrySoup() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; +ComputerscareLaundrySoup() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);} + void process(const ProcessArgs &args) override; json_t *toJson() override { @@ -245,33 +246,33 @@ void onCreate () override }; -void ComputerscareLaundrySoup::step() { +void ComputerscareLaundrySoup::process(const ProcessArgs &args) { bool globalGateIn = globalClockTrigger.isHigh(); bool atFirstStep = false; bool atLastStepAfterIncrement = false; - bool clocked = globalClockTrigger.process(inputs[GLOBAL_CLOCK_INPUT].value); + bool clocked = globalClockTrigger.process(inputs[GLOBAL_CLOCK_INPUT].getVoltage()); bool currentTriggerIsHigh = false; bool currentTriggerClocked = false; - bool globalManualResetClicked = globalManualResetTrigger.process(params[MANUAL_RESET_PARAM].value); - bool globalManualClockClicked = globalManualClockTrigger.process(params[MANUAL_CLOCK_PARAM].value); + bool globalManualResetClicked = globalManualResetTrigger.process(params[MANUAL_RESET_PARAM].getValue()); + bool globalManualClockClicked = globalManualClockTrigger.process(params[MANUAL_CLOCK_PARAM].getValue()); - bool globalResetTriggered = globalResetTriggerInput.process(inputs[GLOBAL_RESET_INPUT].value / 2.f); + bool globalResetTriggered = globalResetTriggerInput.process(inputs[GLOBAL_RESET_INPUT].getVoltage() / 2.f); bool currentResetActive = false; bool currentResetTriggered = false; bool currentManualResetClicked; for(int i = 0; i < numFields; i++) { - currentResetActive = inputs[RESET_INPUT + i].active; - currentResetTriggered = resetTriggers[i].process(inputs[RESET_INPUT+i].value / 2.f); + currentResetActive = inputs[RESET_INPUT + i].isConnected(); + currentResetTriggered = resetTriggers[i].process(inputs[RESET_INPUT+i].getVoltage() / 2.f); currentTriggerIsHigh = clockTriggers[i].isHigh(); - currentTriggerClocked = clockTriggers[i].process(inputs[CLOCK_INPUT + i].value); + currentTriggerClocked = clockTriggers[i].process(inputs[CLOCK_INPUT + i].getVoltage()); - currentManualResetClicked = manualResetTriggers[i].process(params[INDIVIDUAL_RESET_PARAM + i].value); + currentManualResetClicked = manualResetTriggers[i].process(params[INDIVIDUAL_RESET_PARAM + i].getValue()); if(this->laundrySequences[i].numSteps > 0) { - if (inputs[CLOCK_INPUT + i].active) { + if (inputs[CLOCK_INPUT + i].isConnected()) { if(currentTriggerClocked || globalManualClockClicked) { incrementInternalStep(i); activeStep[i] = (this->laundrySequences[i].peekWorkingStep() == 1); @@ -280,7 +281,7 @@ void ComputerscareLaundrySoup::step() { } } else { - if ((inputs[GLOBAL_CLOCK_INPUT].active && clocked) || globalManualClockClicked) { + if ((inputs[GLOBAL_CLOCK_INPUT].isConnected() && clocked) || globalManualClockClicked) { incrementInternalStep(i); activeStep[i] = (this->laundrySequences[i].peekWorkingStep() == 1); atLastStepAfterIncrement = this->laundrySequences[i].atLastStep(); @@ -302,19 +303,19 @@ void ComputerscareLaundrySoup::step() { } else { - if(atFirstStep && !currentResetActive && !inputs[GLOBAL_RESET_INPUT].active) { + if(atFirstStep && !currentResetActive && !inputs[GLOBAL_RESET_INPUT].isConnected()) { //checkIfShouldChange(i); } } } - if(inputs[CLOCK_INPUT + i].active) { - outputs[TRG_OUTPUT + i].value = (currentTriggerIsHigh && activeStep[i]) ? 10.0f : 0.0f; - outputs[FIRST_STEP_OUTPUT + i].value = (currentTriggerIsHigh && atFirstStep) ? 10.f : 0.0f; + if(inputs[CLOCK_INPUT + i].isConnected()) { + outputs[TRG_OUTPUT + i].setVoltage((currentTriggerIsHigh && activeStep[i]) ? 10.0f : 0.0f); + outputs[FIRST_STEP_OUTPUT + i].setVoltage((currentTriggerIsHigh && atFirstStep) ? 10.f : 0.0f); } else { - outputs[TRG_OUTPUT + i].value = (globalGateIn && activeStep[i]) ? 10.0f : 0.0f; - outputs[FIRST_STEP_OUTPUT + i].value = (globalGateIn && atFirstStep) ? 10.f : 0.0f; + outputs[TRG_OUTPUT + i].setVoltage((globalGateIn && activeStep[i]) ? 10.0f : 0.0f); + outputs[FIRST_STEP_OUTPUT + i].setVoltage((globalGateIn && atFirstStep) ? 10.f : 0.0f); } } } @@ -338,8 +339,9 @@ struct ComputerscareLaundrySoupWidget : ModuleWidget { double verticalSpacing = 18.4; int verticalStart = 22; - ComputerscareLaundrySoupWidget(ComputerscareLaundrySoup *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/ComputerscareLaundrySoupPanel.svg"))); + ComputerscareLaundrySoupWidget(ComputerscareLaundrySoup *module) { + setModule(module); + setPanel(APP->window->loadSvg(asset::plugin(plugin, "res/ComputerscareLaundrySoupPanel.svg"))); //global clock input addInput(Port::create<InPort>(mm2px(Vec(2 , 0)), Port::INPUT, module, ComputerscareLaundrySoup::GLOBAL_CLOCK_INPUT)); diff --git a/src/ComputerscareOhPeas.cpp b/src/ComputerscareOhPeas.cpp @@ -1,7 +1,9 @@ +#include "plugin.hpp" #include "Computerscare.hpp" + #include "dtpulse.hpp" #include "dsp/digital.hpp" -#include "window.hpp" +//#include "window.hpp" #include "dsp/filter.hpp" #include <string> @@ -12,40 +14,59 @@ struct ComputerscareOhPeas; const int numChannels= 4; -class PeasTextField : public LedDisplayTextField { +struct PeasTextField; +struct ComputerscareOhPeas; -public: +struct PeasTextField : LedDisplayTextField { + std::shared_ptr<Font> font; + math::Vec textOffset; + NVGcolor color; int fontSize = 16; int rowIndex=0; bool inError = false; - PeasTextField() : LedDisplayTextField() {} + ComputerscareOhPeas* module; + PeasTextField(); + //void draw(const DrawArgs &args) override; + //int getTextPosition(math::Vec mousePos) ; + + void setModule(ComputerscareOhPeas* _module) { module = _module; } - virtual void onTextChange() override; - int getTextPosition(Vec mousePos) override { + void onEnter(const widget::EnterEvent &e) override; + + /*int getTextPosition(Vec mousePos) override { bndSetFont(font->handle); int textPos = bndIconLabelTextPosition(gVg, textOffset.x, textOffset.y, box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, -1, fontSize, text.c_str(), mousePos.x, mousePos.y); bndSetFont(gGuiFont->handle); return textPos; - } - void draw(NVGcontext *vg) override { - nvgScissor(vg, 0, 0, box.size.x, box.size.y); + }*/ + int getTextPosition(math::Vec mousePos) override { + bndSetFont(font->handle); + int textPos = bndIconLabelTextPosition(APP->window->vg, textOffset.x, textOffset.y, + box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, + -1, 12, text.c_str(), mousePos.x, mousePos.y); + bndSetFont(APP->window->uiFont->handle); + return textPos; +} + void draw(const DrawArgs &args) override { + if(module) { + nvgScissor(args.vg, 0, 0, box.size.x, box.size.y); // Background - nvgFontSize(vg, fontSize); - nvgBeginPath(vg); - nvgRoundedRect(vg, 0, 0, box.size.x, box.size.y, 10.0); + nvgFontSize(args.vg, fontSize); + nvgBeginPath(args.vg); + nvgRoundedRect(args.vg, 0, 0, box.size.x, box.size.y, 10.0); if(inError) { - nvgFillColor(vg, COLOR_COMPUTERSCARE_PINK); + nvgFillColor(args.vg, COLOR_COMPUTERSCARE_PINK); } else { - nvgFillColor(vg, nvgRGB(0x00, 0x00, 0x00)); + nvgFillColor(args.vg, nvgRGB(0x00, 0x00, 0x00)); } - nvgFill(vg); + nvgFill(args.vg); // Text if (font->handle >= 0) { @@ -53,23 +74,25 @@ public: NVGcolor highlightColor = color; highlightColor.a = 0.5; - int begin = min(cursor, selection); - int end = (this == gFocusedWidget) ? max(cursor, selection) : -1; - //bndTextField(vg,textOffset.x,textOffset.y+2, box.size.x, box.size.y, -1, 0, 0, const char *text, int cbegin, int cend); - bndIconLabelCaret(vg, textOffset.x, textOffset.y - 3, + int begin = fmin(cursor, selection); + // int end = (this == gFocusedWidget) ? fmax(cursor, selection) : -1; + + int end = fmax(cursor,selection); + //bndTextField(args.vg,textOffset.x,textOffset.y+2, box.size.x, box.size.y, -1, 0, 0, const char *text, int cbegin, int cend); + bndIconLabelCaret(args.vg, textOffset.x, textOffset.y - 3, box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, -1, color, fontSize, text.c_str(), highlightColor, begin, end); - bndSetFont(gGuiFont->handle); + bndSetFont(font->handle); } - nvgResetScissor(vg); + nvgResetScissor(args.vg); }; -private: - ComputerscareOhPeas* module; +} }; + struct ComputerscareOhPeas : Module { enum ParamIds { GLOBAL_TRANSPOSE, @@ -97,23 +120,52 @@ struct ComputerscareOhPeas : Module { NUM_LIGHTS }; - PeasTextField* textField; + int numDivisions = 12; int globalTranspose = 0; bool evenQuantizeMode = true; + std::string currentFormula = "221222"; std::string numDivisionsString = ""; SmallLetterDisplay* numDivisionsDisplay; SmallLetterDisplay* globalTransposeDisplay; + PeasTextField *textField; + // this one throws an error I think Quantizer quant; - ComputerscareOhPeas() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { - quant = Quantizer("221222",12,0); + ComputerscareOhPeas() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + params[GLOBAL_TRANSPOSE].config(-1.f, 1.f, 0.0f, "Global Transpose"); + params[NUM_DIVISIONS].config(1.f, 24.f, 12.0f, "Number of Divisions"); + for(int i = 0; i < numChannels; i++) { + std::string chi = "Ch. "+std::to_string(i+1); + params[ SCALE_TRIM +i].config(-1.f, 1.f, 0.0f, chi+" Scale CV Amount"); + params[ SCALE_VAL +i].config(-5.f, 5.f, 0.0f, chi+" Scale Value"); + params[ OFFSET_TRIM +i].config(-1.f, 1.f, 0.0f, chi+" Offset CV Amount"); + params[ OFFSET_VAL +i].config(-5.f, 5.f, 0.0f, chi+" Offset Value"); + + } + /* + + SCALE_TRIM +i, -1.f, 1.f, 0.0f)); + + + SCALE_VAL +i, -1.f, 1.f, 0.0f)); + + OFFSET_TRIM +i, -1.f, 1.f, 0.0f)); + + + OFFSET_VAL +i, -5.f, 5.f, 0.0f)); + */ + //, 1.f, 24.f, 12.0f NUM_DIVISIONS + //ComputerscareOhPeas::GLOBAL_TRANSPOSE , -1.f, 1.f, 0.0f + + quant = Quantizer(currentFormula,12,0); } - void step() override; - json_t *toJson() override + void process(const ProcessArgs &args) override; + /* json_t *toJson() override { json_t *rootJ = json_object(); @@ -138,18 +190,21 @@ struct ComputerscareOhPeas : Module { } } setQuant(); - } + }*/ + void setQuant() { - std::string value = this->textField->text; - this->quant = Quantizer(value,this->numDivisions,this->globalTranspose); - this->setNumDivisionsString(); + //std::string value = "23";//this->textField->text; + printf("delta %s\n",this->currentFormula.c_str()); + this->quant = Quantizer(this->currentFormula.c_str(),this->numDivisions,this->globalTranspose); + printf("echo \n"); + //this->setNumDivisionsString(); } void setNumDivisionsString() { - std::string transposeString = (this->globalTranspose > 0 ? "+" : "" ) + std::to_string(this->globalTranspose); + /*std::string transposeString = (this->globalTranspose > 0 ? "+" : "" ) + std::to_string(this->globalTranspose); this->numDivisionsDisplay->value = std::to_string(this->numDivisions); - this->globalTransposeDisplay->value = transposeString; + this->globalTransposeDisplay->value = transposeString;*/ } // For more advanced Module features, read Rack's engine.hpp header file @@ -157,15 +212,17 @@ struct ComputerscareOhPeas : Module { // - onSampleRateChange: event triggered by a change of sample rate // - onReset, onRandomize, onCreate, onDelete: implements special behavior when user clicks these from the context menu }; +void PeasTextField::onEnter(const widget::EnterEvent &e) { + module->setQuant(); + } - -void ComputerscareOhPeas::step() { +void ComputerscareOhPeas::process(const ProcessArgs &args) { float A,B,C,D,Q,a,b,c,d; - int numDivisionsKnobValue = floor(params[NUM_DIVISIONS].value); - int iTranspose = floor(numDivisionsKnobValue * params[GLOBAL_TRANSPOSE].value); + int numDivisionsKnobValue = floor(params[NUM_DIVISIONS].getValue()); + int iTranspose = floor(numDivisionsKnobValue * params[GLOBAL_TRANSPOSE].getValue()); - //int globalTransposeKnobValue = (int) clamp(roundf(params[GLOBAL_TRANSPOSE].value), -fNumDiv, fNumDiv); + //int globalTransposeKnobValue = (int) clamp(roundf(params[GLOBAL_TRANSPOSE].getValue()), -fNumDiv, fNumDiv); if(numDivisionsKnobValue != numDivisions) { //printf("%i, %i, %i, %i\n",numDivisionsKnobValue,numDivisions,iTranspose,globalTranspose); @@ -185,22 +242,22 @@ void ComputerscareOhPeas::step() { } for(int i = 0; i < numChannels; i++) { - a = params[SCALE_VAL+i].value; + a = params[SCALE_VAL+i].getValue(); - b = params[SCALE_TRIM+i].value; - B = inputs[SCALE_CV+i].value; - A = inputs[CHANNEL_INPUT+i].value; + b = params[SCALE_TRIM+i].getValue(); + B = inputs[SCALE_CV+i].getVoltage(); + A = inputs[CHANNEL_INPUT+i].getVoltage(); - c = params[OFFSET_TRIM+i].value; - C = inputs[OFFSET_CV+i].value; - d = params[OFFSET_VAL+i].value; + c = params[OFFSET_TRIM+i].getValue(); + C = inputs[OFFSET_CV+i].getVoltage(); + d = params[OFFSET_VAL+i].getValue(); D = (b*B + a)*A + (c*C + d); Q = quant.quantizeEven(D,iTranspose); - outputs[SCALED_OUTPUT + i].value = D; - outputs[QUANTIZED_OUTPUT + i].value = Q; + outputs[SCALED_OUTPUT + i].setVoltage(D); + outputs[QUANTIZED_OUTPUT + i].setVoltage(Q); } } @@ -211,50 +268,48 @@ struct StringDisplayWidget3 : TransparentWidget { std::shared_ptr<Font> font; StringDisplayWidget3() { - font = Font::load(assetPlugin(plugin, "res/Oswald-Regular.ttf")); + font = APP->window->loadFont(asset::plugin(pluginInstance, "res/Oswald-Regular.ttf")); }; - void draw(NVGcontext *vg) override + void draw(const DrawArgs &args) override { // Background NVGcolor backgroundColor = nvgRGB(0x10, 0x00, 0x10); NVGcolor StrokeColor = nvgRGB(0xC0, 0xC7, 0xDE); - nvgBeginPath(vg); - nvgRoundedRect(vg, -1.0, -1.0, box.size.x+2, box.size.y+2, 4.0); - nvgFillColor(vg, StrokeColor); - nvgFill(vg); - nvgBeginPath(vg); - nvgRoundedRect(vg, 0.0, 0.0, box.size.x, box.size.y, 4.0); - nvgFillColor(vg, backgroundColor); - nvgFill(vg); + nvgBeginPath(args.vg); + nvgRoundedRect(args.vg, -1.0, -1.0, box.size.x+2, box.size.y+2, 4.0); + nvgFillColor(args.vg, StrokeColor); + nvgFill(args.vg); + nvgBeginPath(args.vg); + nvgRoundedRect(args.vg, 0.0, 0.0, box.size.x, box.size.y, 4.0); + nvgFillColor(args.vg, backgroundColor); + nvgFill(args.vg); // text - nvgFontSize(vg, 15); - nvgFontFaceId(vg, font->handle); - nvgTextLetterSpacing(vg, 2.5); + nvgFontSize(args.vg, 15); + nvgFontFaceId(args.vg, font->handle); + nvgTextLetterSpacing(args.vg, 2.5); std::stringstream to_display; to_display << std::setw(8) << *value; Vec textPos = Vec(6.0f, 12.0f); NVGcolor textColor = nvgRGB(0xC0, 0xE7, 0xDE); - nvgFillColor(vg, textColor); - nvgTextBox(vg, textPos.x, textPos.y,80,to_display.str().c_str(), NULL); + nvgFillColor(args.vg, textColor); + nvgTextBox(args.vg, textPos.x, textPos.y,80,to_display.str().c_str(), NULL); } }; -void PeasTextField::onTextChange() { - module->setQuant(); -} + struct SetScaleMenuItem : MenuItem { ComputerscareOhPeas *peas; std::string scale="221222"; SetScaleMenuItem(std::string scaleInput) { scale=scaleInput; } - void onAction(EventAction &e) override { - peas->textField->text = scale; + void doAction() { + //peas->textField->text = scale; peas->setQuant(); } }; @@ -264,7 +319,7 @@ struct SetQuantizationModeMenuItem : MenuItem { SetQuantizationModeMenuItem(bool evenMode) { mode=evenMode; } - void onAction(EventAction &e) override { + void doAction() { peas->evenQuantizeMode = mode; } void step() override { @@ -272,25 +327,46 @@ struct SetQuantizationModeMenuItem : MenuItem { MenuItem::step(); } }; +struct PeasTF2 : LedDisplayTextField { + ComputerscareOhPeas *module; + //ComputerscareDebug *module; + PeasTF2() { + LedDisplayTextField(); + }; + void draw(const DrawArgs &args) override { + if(module) { + if(text.c_str()!=module->currentFormula) { + printf("alpha %s\n",text.c_str()); + module->currentFormula = text.c_str(); + printf("bravo %s\n",text.c_str()); + module->setQuant(); + printf("charlie %s\n",text.c_str()); + } + } + LedDisplayTextField::draw(args); + } + //void draw(const DrawArgs &args) override; + //int getTextPosition(math::Vec mousePos) override; +}; +struct PeasSmallDisplay : SmallLetterDisplay { + ComputerscareOhPeas *module; + PeasSmallDisplay() { + SmallLetterDisplay(); + }; + void draw(const DrawArgs &args) { + SmallLetterDisplay::draw(args); + } +}; +//this->numDivisions,this->globalTranspose struct ComputerscareOhPeasWidget : ModuleWidget { float randAmt = 0.f; - ComputerscareOhPeasWidget(ComputerscareOhPeas *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/ComputerscareOhPeasPanel.svg"))); -/* - addInput(Port::create<InPort>(Vec(3, 330), Port::INPUT, module, ComputerscareOhPeas::TRG_INPUT)); - addInput(Port::create<InPort>(Vec(33, 330), Port::INPUT, module, ComputerscareOhPeas::VAL_INPUT)); - addInput(Port::create<InPort>(Vec(63, 330), Port::INPUT, module, ComputerscareOhPeas::CLR_INPUT)); - - addParam(ParamWidget::create<LEDButton>(Vec(6, 290), module, ComputerscareOhPeas::MANUAL_TRIGGER, 0.0, 1.0, 0.0)); - addParam(ParamWidget::create<LEDButton>(Vec(66, 290), module, ComputerscareOhPeas::MANUAL_CLEAR_TRIGGER, 0.0, 1.0, 0.0)); - - StringDisplayWidget3 *display = new StringDisplayWidget3(); - display->box.pos = Vec(1,24); - display->box.size = Vec(88, 250); - display->value = &module->strValue; - addChild(display); -*/ + //PeasTextField* textFieldTemp; + + //TextField *textFieldTemp; + ComputerscareOhPeasWidget(ComputerscareOhPeas *module) { + setModule(module); + setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/ComputerscareOhPeasPanel.svg"))); double x = 1; double y = 7; @@ -298,76 +374,90 @@ struct ComputerscareOhPeasWidget : ModuleWidget { double dx = 9.95; double xx; double yy=18; + addParam(createParam<MediumSnapKnob>(mm2px(Vec(11,yy-2)), module, ComputerscareOhPeas::NUM_DIVISIONS )); + + addParam(createParam<SmoothKnob>(mm2px(Vec(21,yy-2)), module, ComputerscareOhPeas::GLOBAL_TRANSPOSE)); - - ParamWidget* numDivisionKnob = ParamWidget::create<MediumSnapKnob>(mm2px(Vec(11,yy-2)), module, ComputerscareOhPeas::NUM_DIVISIONS , 1.f, 24.f, 12.0f); - addParam(numDivisionKnob); - - ParamWidget* rootKnob = ParamWidget::create<SmoothKnob>(mm2px(Vec(21,yy-2)), module, ComputerscareOhPeas::GLOBAL_TRANSPOSE , -1.f, 1.f, 0.0f); - addParam(rootKnob); - - textFieldTemp = Widget::create<PeasTextField>(mm2px(Vec(x,y+24))); - textFieldTemp->setModule(module); + textFieldTemp = createWidget<PeasTF2>(mm2px(Vec(x,y+24))); + textFieldTemp->module = module; + //textFieldTemp->setModule(module); textFieldTemp->box.size = mm2px(Vec(44, 7)); textFieldTemp->multiline = false; - textFieldTemp->color = nvgRGB(0xC0, 0xE7, 0xDE); + //textFieldTemp->color = nvgRGB(0xC0, 0xE7, 0xDE); textFieldTemp->text = "221222"; addChild(textFieldTemp); - module->textField = textFieldTemp; + //module->textField = textFieldTemp; - ndd = new SmallLetterDisplay(); + ndd = new PeasSmallDisplay(); + ndd->module = module; ndd->box.pos = mm2px(Vec(2,yy)); ndd->box.size = mm2px(Vec(9, 7)); ndd->value = ""; ndd->baseColor = COLOR_COMPUTERSCARE_LIGHT_GREEN; addChild(ndd); - module->numDivisionsDisplay = ndd; + //module->numDivisionsDisplay = ndd; transposeDisplay = new SmallLetterDisplay(); + transposeDisplay->box.pos = mm2px(Vec(30,yy)); transposeDisplay->box.size = mm2px(Vec(11, 7)); transposeDisplay->letterSpacing = 2.f; transposeDisplay->value = ""; transposeDisplay->baseColor = COLOR_COMPUTERSCARE_LIGHT_GREEN; addChild(transposeDisplay); - module->globalTransposeDisplay = transposeDisplay; + //module->globalTransposeDisplay = transposeDisplay; for(int i = 0; i < numChannels; i++) { - xx = x + dx*i+randAmt*(2*randomUniform()-.5); - y+=randAmt*(randomUniform()-.5); - addInput(Port::create<InPort>(mm2px(Vec(xx, y-0.8)), Port::INPUT, module, ComputerscareOhPeas::CHANNEL_INPUT+i)); + xx = x + dx*i+randAmt*(2*random::uniform()-.5); + y+=randAmt*(random::uniform()-.5); + addInput(createInput<InPort>(mm2px(Vec(xx, y-0.8)), module, ComputerscareOhPeas::CHANNEL_INPUT+i)); - ParamWidget* scaleTrimKnob = ParamWidget::create<SmallKnob>(mm2px(Vec(xx+2,y+34)), module, ComputerscareOhPeas::SCALE_TRIM +i, -1.f, 1.f, 0.0f); - addParam(scaleTrimKnob); + addParam(createParam<SmallKnob>(mm2px(Vec(xx+2,y+34)), module, ComputerscareOhPeas::SCALE_TRIM +i)); - addInput(Port::create<InPort>(mm2px(Vec(xx, y+40)), Port::INPUT, module, ComputerscareOhPeas::SCALE_CV+i)); + addInput(createInput<InPort>(mm2px(Vec(xx, y+40)), module, ComputerscareOhPeas::SCALE_CV+i)); - ParamWidget* scaleKnob = ParamWidget::create<SmoothKnob>(mm2px(Vec(xx,y+50)), module, ComputerscareOhPeas::SCALE_VAL +i, -1.f, 1.f, 0.0f); - addParam(scaleKnob); + addParam(createParam<SmoothKnob>(mm2px(Vec(xx,y+50)), module, ComputerscareOhPeas::SCALE_VAL +i)); - ParamWidget* offsetTrimKnob = ParamWidget::create<ComputerscareDotKnob>(mm2px(Vec(xx+2,y+64)), module, ComputerscareOhPeas::OFFSET_TRIM +i, -1.f, 1.f, 0.0f); - addParam(offsetTrimKnob); + addParam(createParam<ComputerscareDotKnob>(mm2px(Vec(xx+2,y+64)), module, ComputerscareOhPeas::OFFSET_TRIM +i)); - addInput(Port::create<InPort>(mm2px(Vec(xx, y+70)), Port::INPUT, module, ComputerscareOhPeas::OFFSET_CV+i)); + addInput(createInput<InPort>(mm2px(Vec(xx, y+70)), module, ComputerscareOhPeas::OFFSET_CV+i)); - ParamWidget* offsetKnob = ParamWidget::create<SmoothKnob>(mm2px(Vec(xx,y+80)), module, ComputerscareOhPeas::OFFSET_VAL +i, -5.f, 5.f, 0.0f); - addParam(offsetKnob); + addParam(createParam<SmoothKnob>(mm2px(Vec(xx,y+80)), module, ComputerscareOhPeas::OFFSET_VAL +i)); - addOutput(Port::create<OutPort>(mm2px(Vec(xx , y+93)), Port::OUTPUT, module, ComputerscareOhPeas::SCALED_OUTPUT + i)); + addOutput(createOutput<OutPort>(mm2px(Vec(xx , y+93)), module, ComputerscareOhPeas::SCALED_OUTPUT + i)); - addOutput(Port::create<InPort>(mm2px(Vec(xx+1 , y+108)), Port::OUTPUT, module, ComputerscareOhPeas::QUANTIZED_OUTPUT + i)); + addOutput(createOutput<InPort>(mm2px(Vec(xx+1 , y+108)), module, ComputerscareOhPeas::QUANTIZED_OUTPUT + i)); } - module->setQuant(); } - SmallLetterDisplay* trimPlusMinus; - SmallLetterDisplay* ndd; - SmallLetterDisplay* transposeDisplay; + json_t *toJson() override { + json_t *rootJ = ModuleWidget::toJson(); + + // text + json_object_set_new(rootJ, "sequences", json_string(textFieldTemp->text.c_str())); + + return rootJ; + } - PeasTextField* textFieldTemp; - Menu *createContextMenu() override; + void fromJson(json_t *rootJ) override { + ModuleWidget::fromJson(rootJ); + + // text + json_t *textJ = json_object_get(rootJ, "sequences"); + if (textJ) + textFieldTemp->text = json_string_value(textJ); + + //module->setQuant(); + } + +PeasTF2 *textFieldTemp; + SmallLetterDisplay* trimPlusMinus; + PeasSmallDisplay* ndd; + SmallLetterDisplay* transposeDisplay; + //PeasTextField* textFieldTemp; + //Menu *createContextMenu(); }; @@ -386,7 +476,7 @@ void quantizationModeMenuItemAdd(ComputerscareOhPeas* peas, Menu* menu, bool eve menu->addChild(menuItem); } -Menu *ComputerscareOhPeasWidget::createContextMenu() { +/*Menu *ComputerscareOhPeasWidget::createContextMenu() { Menu *menu = ModuleWidget::createContextMenu(); ComputerscareOhPeas *peas = dynamic_cast<ComputerscareOhPeas*>(module); assert(peas); @@ -394,20 +484,6 @@ Menu *ComputerscareOhPeasWidget::createContextMenu() { MenuLabel *spacerLabel = new MenuLabel(); menu->addChild(spacerLabel); - /* - // "closest" quantization mode is quite a bit slower than even - MenuLabel *quantModeLabel = new MenuLabel(); - quantModeLabel->text = "Quantization Mode"; - menu->addChild(quantModeLabel); - - quantizationModeMenuItemAdd(peas,menu,true,"Even"); - quantizationModeMenuItemAdd(peas,menu,false,"Closest"); - - - - MenuLabel *spacerLabel2 = new MenuLabel(); - menu->addChild(spacerLabel2);*/ - MenuLabel *modeLabel = new MenuLabel(); modeLabel->text = "Scale Presets"; @@ -428,10 +504,29 @@ Menu *ComputerscareOhPeasWidget::createContextMenu() { scaleItemAdd(peas,menu,"343","Minor 7 Tetrachord"); return menu; -} + + // "closest" quantization mode is quite a bit slower than even + MenuLabel *quantModeLabel = new MenuLabel(); + quantModeLabel->text = "Quantization Mode"; + menu->addChild(quantModeLabel); + + quantizationModeMenuItemAdd(peas,menu,true,"Even"); + quantizationModeMenuItemAdd(peas,menu,false,"Closest"); + + + + MenuLabel *spacerLabel2 = new MenuLabel(); + menu->addChild(spacerLabel2); + + +}*/ // Specify the Module and ModuleWidget subclass, human-readable // author name for categorization per plugin, module slug (should never // change), human-readable module name, and any number of tags // (found in `include/tags.hpp`) separated by commas. -Model *modelComputerscareOhPeas = Model::create<ComputerscareOhPeas, ComputerscareOhPeasWidget>("computerscare", "computerscare-ohpeas", "Oh Peas! Quad Quantenuverter", QUANTIZER_TAG, ATTENUATOR_TAG, QUAD_TAG, UTILITY_TAG); + + +//Model *modelComputerscareDebug = createModel<ComputerscareDebug, ComputerscareDebugWidget>("computerscare-debug"); + +Model *modelComputerscareOhPeas = createModel<ComputerscareOhPeas, ComputerscareOhPeasWidget>("computerscare-ohpeas"); diff --git a/src/ComputerscarePatchSequencer.cpp b/src/ComputerscarePatchSequencer.cpp @@ -62,8 +62,9 @@ struct ComputerscarePatchSequencer : Module { int randomizationStepEnum = 0; //0: edit step, 1: active step, 2: all steps int randomizationOutputBoundsEnum = 1; //0: randomize exactly one per output, 1: randomize exactly one per output, 2: randomize 1 or more, 3: randomize 0 or more -ComputerscarePatchSequencer() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; +ComputerscarePatchSequencer() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);} + void process(const ProcessArgs &args) override; @@ -163,17 +164,17 @@ json_t *randomizationOutputBoundsEnumJ = json_object_get(rootJ, "randomizationOu for (int i = 0; i < 10; i++) { - if(inputs[INPUT_JACKS + i].active) { + if(inputs[INPUT_JACKS + i].isConnected()) { numConnectedInputs++; connectedInputIndices.push_back(i); } - connectedInputs[i] = inputs[INPUT_JACKS + i].active; - connectedOutputs[i] = outputs[OUTPUTS + i].active; + connectedInputs[i] = inputs[INPUT_JACKS + i].isConnected(); + connectedOutputs[i] = outputs[OUTPUTS + i].isConnected(); } for(int k = 0; k < maxSteps; k++) { if((randomizationStepEnum == 0 && k == editAddress) || (randomizationStepEnum == 1 && k == address) || randomizationStepEnum == 2) { for(int i = 0; i < 10; i++) { - randomIndex = numConnectedInputs > 0 ? connectedInputIndices[floor(randomUniform()*numConnectedInputs)] : 0; + randomIndex = numConnectedInputs > 0 ? connectedInputIndices[floor(random::uniform()*numConnectedInputs)] : 0; if(connectedOutputs[i]) { for (int j = 0; j < 10; j++) { if(j==randomIndex) @@ -194,18 +195,18 @@ json_t *randomizationOutputBoundsEnumJ = json_object_get(rootJ, "randomizationOu if((randomizationStepEnum == 0 && k == editAddress) || (randomizationStepEnum == 1 && k == address) || randomizationStepEnum == 2) { for (int i = 0; i < 10; i++) { - randomIndex = floor(randomUniform()*10); + randomIndex = floor(random::uniform()*10); for (int j = 0; j < 10; j++) { if(randomizationOutputBoundsEnum == 3) { - switch_states[k][j][i] = (j==randomIndex || randomUniform() < 0.2) ? 1 : 0; + switch_states[k][j][i] = (j==randomIndex || random::uniform() < 0.2) ? 1 : 0; } else if(randomizationOutputBoundsEnum == 2) { - switch_states[k][j][i] = randomUniform() < 0.2 ? 1 : 0; + switch_states[k][j][i] = random::uniform() < 0.2 ? 1 : 0; } else if(randomizationOutputBoundsEnum == 0) { - switch_states[k][j][i] = (j==randomIndex && randomUniform() < 0.7) ? 1 : 0; + switch_states[k][j][i] = (j==randomIndex && random::uniform() < 0.7) ? 1 : 0; } else { switch_states[k][j][i] = j==randomIndex ? 1 : 0; @@ -235,9 +236,9 @@ json_t *randomizationOutputBoundsEnumJ = json_object_get(rootJ, "randomizationOu }; -void ComputerscarePatchSequencer::step() { +void ComputerscarePatchSequencer::process(const ProcessArgs &args) { - int numStepsKnobPosition = (int) clamp(roundf(params[STEPS_PARAM].value), 1.0f, 16.0f); + int numStepsKnobPosition = (int) clamp(roundf(params[STEPS_PARAM].getValue()), 1.0f, 16.0f); for ( int i = 0 ; i < 10 ; i++) @@ -249,7 +250,7 @@ void ComputerscarePatchSequencer::step() { { for (int j = 0 ; j < 10 ; j++) { - if (switch_triggers[i][j].process(params[SWITCHES+j*10 + i].value)) + if (switch_triggers[i][j].process(params[SWITCHES+j*10 + i].getValue())) { // handle button clicks in the patch matrix switch_states[editAddress][i][j] = !switch_states[editAddress][i][j]; @@ -264,28 +265,28 @@ void ComputerscarePatchSequencer::step() { numAddresses = numStepsKnobPosition; } - if(randomizeTrigger.process(inputs[RANDOMIZE_INPUT].value / 2.f)) { + if(randomizeTrigger.process(inputs[RANDOMIZE_INPUT].getVoltage() / 2.f)) { randomizePatchMatrix(); } - if(nextAddressEdit.process(params[EDIT_PARAM].value) ) { + if(nextAddressEdit.process(params[EDIT_PARAM].getValue()) ) { editAddress = editAddress + 1; editAddress = editAddress % maxSteps; } - if(prevAddressEdit.process(params[EDIT_PREV_PARAM].value) ) { + if(prevAddressEdit.process(params[EDIT_PREV_PARAM].getValue()) ) { editAddress = editAddress - 1; editAddress = editAddress + maxSteps; editAddress = editAddress % maxSteps; } - if(nextAddressRead.process(params[MANUAL_CLOCK_PARAM].value) || clockTrigger.process(inputs[TRG_INPUT].value / 2.f)) { - numAddresses = (int) clamp(roundf(params[STEPS_PARAM].value /*+ inputs[STEPS_INPUT].value*/), 1.0f, 16.0f); + if(nextAddressRead.process(params[MANUAL_CLOCK_PARAM].getValue()) || clockTrigger.process(inputs[TRG_INPUT].getVoltage() / 2.f)) { + numAddresses = (int) clamp(roundf(params[STEPS_PARAM].getValue() /*+ inputs[STEPS_INPUT].getVoltage()*/), 1.0f, 16.0f); address = address + 1; address = address % numAddresses; } - if(resetTriggerButton.process(params[RESET_PARAM].value) || resetTriggerInput.process(inputs[RESET_INPUT].value / 2.f)) { - numAddresses = (int) clamp(roundf(params[STEPS_PARAM].value), 1.0f, 16.0f); + if(resetTriggerButton.process(params[RESET_PARAM].getValue()) || resetTriggerInput.process(inputs[RESET_INPUT].getVoltage() / 2.f)) { + numAddresses = (int) clamp(roundf(params[STEPS_PARAM].getValue()), 1.0f, 16.0f); address = 0; } @@ -295,7 +296,7 @@ void ComputerscarePatchSequencer::step() { for (int i = 0 ; i < 10 ; i++) { - input_values[i] = inputs[INPUT_JACKS + i].value; + input_values[i] = inputs[INPUT_JACKS + i].getVoltage(); } for (int i = 0 ; i < 10 ; i++) @@ -312,7 +313,7 @@ void ComputerscarePatchSequencer::step() { /// outputs for (int i = 0 ; i < 10 ; i++) { - outputs[OUTPUTS + i].value = sums[i]; + outputs[OUTPUTS + i].setVoltage(sums[i]); } } @@ -323,31 +324,31 @@ struct NumberDisplayWidget3 : TransparentWidget { std::shared_ptr<Font> font; NumberDisplayWidget3() { - font = Font::load(assetPlugin(plugin, "res/digital-7.ttf")); + font = APP->window->loadFont(asset::plugin(plugin, "res/digital-7.ttf")); }; - void draw(NVGcontext *vg) override + void draw(const DrawArgs &args) override { // Background NVGcolor backgroundColor = nvgRGB(0x00, 0x00, 0x00); - nvgBeginPath(vg); - nvgRoundedRect(vg, 0.0, 0.0, box.size.x, box.size.y, 4.0); - nvgFillColor(vg, backgroundColor); - nvgFill(vg); + nvgBeginPath(args.vg); + nvgRoundedRect(args.vg, 0.0, 0.0, box.size.x, box.size.y, 4.0); + nvgFillColor(args.vg, backgroundColor); + nvgFill(args.vg); // text - nvgFontSize(vg, 13); - nvgFontFaceId(vg, font->handle); - nvgTextLetterSpacing(vg, 2.5); + nvgFontSize(args.vg, 13); + nvgFontFaceId(args.vg, font->handle); + nvgTextLetterSpacing(args.vg, 2.5); std::stringstream to_display; to_display << std::setw(3) << *value; Vec textPos = Vec(6.0f, 17.0f); NVGcolor textColor = nvgRGB(0xC0, 0xE7, 0xDE); - nvgFillColor(vg, textColor); - nvgText(vg, textPos.x, textPos.y, to_display.str().c_str(), NULL); + nvgFillColor(args.vg, textColor); + nvgText(args.vg, textPos.x, textPos.y, to_display.str().c_str(), NULL); } }; @@ -355,8 +356,9 @@ struct NumberDisplayWidget3 : TransparentWidget { struct ComputerscarePatchSequencerWidget : ModuleWidget { - ComputerscarePatchSequencerWidget(ComputerscarePatchSequencer *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/ComputerscarePatchSequencerPanel.svg"))); + ComputerscarePatchSequencerWidget(ComputerscarePatchSequencer *module) { + setModule(module); + setPanel(APP->window->loadSvg(asset::plugin(plugin, "res/ComputerscarePatchSequencerPanel.svg"))); int top_row = 70; int row_spacing = 26; @@ -449,7 +451,7 @@ struct OnlyRandomizeActiveMenuItem : MenuItem { void onAction(EventAction &e) override { patchSequencer->onlyRandomizeActive = !patchSequencer->onlyRandomizeActive; } - void step() override { + void process(const ProcessArgs &args) override { rightText = patchSequencer->onlyRandomizeActive ? "✔" : ""; } }; @@ -460,7 +462,7 @@ struct WhichStepToRandomizeItem : MenuItem { void onAction(EventAction &e) override { patchSequencer->setRandomizationStepEnum(stepEnum); } - void step() override { + void process(const ProcessArgs &args) override { rightText = CHECKMARK(patchSequencer->getRandomizationStepEnum() == stepEnum); MenuItem::step(); } @@ -472,7 +474,7 @@ struct WhichRandomizationOutputBoundsItem : MenuItem { void onAction(EventAction &e) override { patchSequencer->setRandomizationOutputBoundsEnum(boundsEnum); } - void step() override { + void process(const ProcessArgs &args) override { rightText = CHECKMARK(patchSequencer->getRandomizationOutputBoundsEnum() == boundsEnum); MenuItem::step(); } diff --git a/src/dtpulse.cpp b/src/dtpulse.cpp @@ -365,6 +365,9 @@ bool matchParens(std::string value) { theyMatch = (parensCount==0) && (squareCount ==0) && (curlyCount==0) && (angleCount==0); return theyMatch; } + void printVector(std::vector <int> intVector) { + printf("vector\n"); + } void whoKnows(std::string input) { //AbsoluteSequence abs = AbsoluteSequence(input,knobandinputlookup); /*abs.print();