diff --git a/res/Blue_V2Switch_0.svg b/res/Blue_V2Switch_0.svg new file mode 100644 index 0000000..df00831 --- /dev/null +++ b/res/Blue_V2Switch_0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/Blue_V2Switch_1.svg b/res/Blue_V2Switch_1.svg new file mode 100644 index 0000000..06ff283 --- /dev/null +++ b/res/Blue_V2Switch_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/Purple_V2Switch_0.svg b/res/Purple_V2Switch_0.svg new file mode 100644 index 0000000..917b5ea --- /dev/null +++ b/res/Purple_V2Switch_0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/Purple_V2Switch_1.svg b/res/Purple_V2Switch_1.svg new file mode 100644 index 0000000..0107197 --- /dev/null +++ b/res/Purple_V2Switch_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/res/StochSeq.svg b/res/StochSeq.svg index 29ec8ea..ed9fa4c 100644 --- a/res/StochSeq.svg +++ b/res/StochSeq.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/StochSeq.cpp b/src/StochSeq.cpp index 2a2215b..f87090b 100644 --- a/src/StochSeq.cpp +++ b/src/StochSeq.cpp @@ -4,6 +4,44 @@ #define SLIDER_TOP 4 #define NUM_OF_SLIDERS 32 #define NUM_OF_LIGHTS 32 +#define NUM_OF_MEM_BANK 12 + +struct MemoryBank { + bool isOn; + int length; + float *gateProbabilities = new float[NUM_OF_SLIDERS]; + + MemoryBank() { + isOn = false; + length = NUM_OF_SLIDERS; + + for (int i = 0; i < NUM_OF_SLIDERS; i++) { + gateProbabilities[i] = 0.0; + } + } + + ~MemoryBank() { + delete[] gateProbabilities; + } + + void setProbabilities(const float *probs, int size) { + isOn = true; + length = size; + DEBUG("size: %d", size); + DEBUG("length: %d", length); + + for (int i = 0; i < length; i++) { + gateProbabilities[i] = probs[i]; + } + } + + void clearBank() { + isOn = false; + for (int i = 0; i < NUM_OF_SLIDERS; i++) { + gateProbabilities[i] = 0.0; + } + } +}; struct StochSeq : Module, Quantize { enum ModeIds { @@ -70,6 +108,9 @@ struct StochSeq : Module, Quantize { float pitchVoltage = 0.0; float invPitchVoltage = 0.0; float *gateProbabilities = new float[NUM_OF_SLIDERS]; + MemoryBank memBanks[NUM_OF_MEM_BANK]; + // float memBanks[NUM_OF_MEM_BANK][NUM_OF_SLIDERS] = {}; + int currentMemBank = 0; bool enableKBShortcuts = true; bool isCtrlClick = false; @@ -101,6 +142,12 @@ struct StochSeq : Module, Quantize { configOutput(GATES_OUTPUT + i, "Gate " + std::to_string(i+1)); } + // for (int i = 0; i < NUM_OF_MEM_BANK; i++) { + // for (int j = 0; j < NUM_OF_SLIDERS; j++) { + // memBanks[i][j] = 0.0; + // } + // } + randLight = static_cast(random::uniform() * NUM_OF_LIGHTS); } @@ -526,6 +573,58 @@ struct StochSeqDisplay : Widget { } }; +struct MemoryBankDisplay : Widget { + StochSeq *module; + int bankId; + float sliderWidth = 1.25; + + MemoryBankDisplay() {} + + void onButton(const event::Button &e) override { + if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT) { + e.consume(this); + int visibleSliders = (int)module->params[StochSeq::LENGTH_PARAM].getValue(); + module->memBanks[bankId].setProbabilities(module->gateProbabilities, visibleSliders); + + // select from bank + // highlight too + } + } + + float getSliderHeight(int index) { + float y = box.size.y; + return y - (y * module->memBanks[bankId].gateProbabilities[index]); + } + + void draw(const DrawArgs& args) override { + + if (module == NULL) { + // draw for preview + + return; + } + + + + if (module->memBanks[bankId].isOn) { + + // sliders + nvgStrokeColor(args.vg, nvgRGB(60, 70, 73)); + sliderWidth = box.size.x / (float)module->memBanks[bankId].length; + for (int i = 0; i < module->memBanks[bankId].length; i++) { + float sHeight = getSliderHeight(i); + + nvgFillColor(args.vg, nvgRGBA(255, 255, 255, 220)); // bars + nvgBeginPath(args.vg); + nvgRect(args.vg, i * sliderWidth, sHeight, sliderWidth, box.size.y - sHeight); + nvgFill(args.vg); + } + + } + } + +}; + struct StochSeqWidget : ModuleWidget { StochSeqWidget(StochSeq* module) { setModule(module); @@ -534,9 +633,18 @@ struct StochSeqWidget : ModuleWidget { StochSeqDisplay *display = new StochSeqDisplay(); display->module = module; display->box.pos = Vec(7.4, 47.7); - display->box.size = Vec(480, 141.9); + display->box.size = Vec(480, 102.9); // Vec(480, 141.9) addChild(display); + for (int i = 0; i < NUM_OF_MEM_BANK; i++) { + MemoryBankDisplay *memDisplay = new MemoryBankDisplay(); + memDisplay->module = module; + memDisplay->bankId = i; + memDisplay->box.pos = Vec(7.6 + (i * 40), 160.8); + memDisplay->box.size = Vec(40, 28.9); + addChild(memDisplay); + } + addChild(createWidget(Vec(25.9, 2))); addChild(createWidget(Vec(25.9, box.size.y-14))); addChild(createWidget(Vec(457.1, 2))); diff --git a/src/plugin.hpp b/src/plugin.hpp index b486f13..bae6ee7 100644 --- a/src/plugin.hpp +++ b/src/plugin.hpp @@ -123,6 +123,12 @@ struct CenterAlignedLabel : Widget { /************************** PORTS **************************/ +struct DefaultPort : SvgPort { + DefaultPort() { + setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/DefaultPort.svg"))); + } +}; + struct TinyPortPurple : SvgPort { TinyPortPurple() { setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/TinyPortPurple.svg"))); @@ -457,6 +463,7 @@ struct BlueInvertKnob : RoundKnob { // shadow->opacity = 0; setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BlueInvertKnob.svg"))); snap = true; + shadow->blurRadius = 2.0; } };