[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/starlingcode/Via-for-Rack/v2/src/gateseq.cpp [Back]  [Original]

#include "gateseq.hpp"
#include "via-module.hpp"
#include "osdialog.h"

#define GATESEQ_OVERSAMPLE_AMOUNT 1
#define GATESEQ_OVERSAMPLE_QUALITY 1

struct Gateseq : Via  {

    struct PatternIQuantity;
    struct PatternIModQuantity;
    struct PatternIIQuantity;
    struct SHIButtonQuantity;
    struct GateIButtonQuantity;
    struct SeqIButtonQuantity;
    struct SHIIButtonQuantity;
    struct GateIIButtonQuantity;
    struct SeqIIButtonQuantity;
    struct ModulationQuantity;
    struct ModulationCVQuantity;
    struct ButtonQuantity;
    
    Gateseq() : Via(), virtualModule(asset::plugin(pluginInstance, "res/original.gateseq")) {

        virtualIO = &virtualModule;

        config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
        configParam(KNOB1_PARAM, 0, 4095.0, 2048.0, "Pattern I select", "", 0.0, 1.0/4095.0);
        configParam(KNOB2_PARAM, 0, 4095.0, 2048.0, "Pattern I modulation", "", 0.0, 1.0/4095.0);
        configParam(KNOB3_PARAM, 0, 4095.0, 2048.0, "Pattern II select", "", 0.0, 1.0/4095.0);
        configParam(B_PARAM, -1.0, 1.0, -1.0, "Pattern II gate level");
        configParam(CV2AMT_PARAM, 0, 1.0, 1.0, "Pattern I modulation CV amount");
        configParam(A_PARAM, -5.0, 5.0, 5.0, "Pattern I gate level");
        configParam(CV3AMT_PARAM, 0, 1.0, 1.0, "Pattern II density CV amount");
        
        configParam(BUTTON1_PARAM, 0.0, 1.0, 0.0, "A channel/ PTN I S+H control");
        configParam(BUTTON2_PARAM, 0.0, 1.0, 0.0, "A channel/ PTN I gate control");
        configParam(BUTTON3_PARAM, 0.0, 1.0, 0.0, "Pattern I mode");
        configParam(BUTTON4_PARAM, 0.0, 1.0, 0.0, "B channel/ PTN II S+H control");
        configParam(BUTTON5_PARAM, 0.0, 1.0, 0.0, "B channel/ PTN II gate control");
        configParam(BUTTON6_PARAM, 0.0, 1.0, 0.0, "Pattern II patterns");
        
        configParam(TRIGBUTTON_PARAM, 0.0, 5.0, 0.0, "Pattern reset");

        configInput(A_INPUT, "A");
        configInput(B_INPUT, "B");
        configInput(CV1_INPUT, "I pattern");
        configInput(CV2_INPUT, "I modulation");
        configInput(CV3_INPUT, "II pattern");
        configInput(MAIN_LOGIC_INPUT, "Gate");
        configInput(AUX_LOGIC_INPUT, "Reset");

        configOutput(MAIN_OUTPUT, "A + B");
        configOutput(LOGICA_OUTPUT, "Sequencer I");
        configOutput(AUX_DAC_OUTPUT, "Sequencer II");
        configOutput(AUX_LOGIC_OUTPUT, "Logic");

        onSampleRateChange();

        presetData[0] = virtualModule.gateseqUI.stockPreset1;
        presetData[1] = virtualModule.gateseqUI.stockPreset2;
        presetData[2] = virtualModule.gateseqUI.stockPreset3;
        presetData[3] = virtualModule.gateseqUI.stockPreset4;
        presetData[4] = virtualModule.gateseqUI.stockPreset5;
        presetData[5] = virtualModule.gateseqUI.stockPreset6;
    }
    
    void process(const ProcessArgs &args) override;

    ViaGateseq virtualModule;

    void onSampleRateChange() override {

        float sampleRate = APP->engine->getSampleRate();

        ledDecay = 16.0/sampleRate;

        if (sampleRate == 44100.0) {
            virtualModule.sequencer.virtualTimer4Overflow = 44;
        } else if (sampleRate == 48000.0) {
            virtualModule.sequencer.virtualTimer4Overflow = 48;
        } else if (sampleRate == 88200.0) {
            virtualModule.sequencer.virtualTimer4Overflow = 88;
        } else if (sampleRate == 96000.0) {
            virtualModule.sequencer.virtualTimer4Overflow = 96;
        } else if (sampleRate == 176400.0) {
            virtualModule.sequencer.virtualTimer4Overflow = 176;
        } else if (sampleRate == 192000.0) {
            virtualModule.sequencer.virtualTimer4Overflow = 192;
        } else if (sampleRate == 352800.0) {
            virtualModule.sequencer.virtualTimer4Overflow = 353;
        } else if (sampleRate == 384000.0) {
            virtualModule.sequencer.virtualTimer4Overflow = 384;
        } else if (sampleRate == 705600.0) {
            virtualModule.sequencer.virtualTimer4Overflow = 706;
        } else if (sampleRate == 768000.0) {
            virtualModule.sequencer.virtualTimer4Overflow = 768;
        }
        
    }

    json_t *dataToJson() override {

        json_t *rootJ = json_object();
        
        json_object_set_new(rootJ, "gateseq_modes", json_integer(virtualModule.gateseqUI.modeStateBuffer));
        json_object_set_new(rootJ, "logic_mode", json_integer((int) virtualModule.gateseqUI.aux2Mode));
     
        json_object_set_new(rootJ, "patterns_file", json_string(patternsPath.c_str()));
        return rootJ;
    }
    
    void dataFromJson(json_t *rootJ) override {

        json_t *modesJ = json_object_get(rootJ, "gateseq_modes");
        if (modesJ) {
            virtualModule.gateseqUI.modeStateBuffer = json_integer_value(modesJ);
            virtualModule.gateseqUI.loadFromEEPROM(0);
            virtualModule.gateseqUI.recallModuleState();
        }

        json_t *pathJ = json_object_get(rootJ, "patterns_file");
        if (pathJ) {
            patternsPath = json_string_value(pathJ);
            virtualModule.readPatternsFromFile(patternsPath);
            virtualModule.handleButton3ModeChange(virtualModule.gateseqUI.button3Mode);
            virtualModule.handleButton6ModeChange(virtualModule.gateseqUI.button6Mode);
        }
    }
    
    std::string patternsPath = asset::plugin(pluginInstance, "res/original.gateseq");
};

void Gateseq::process(const ProcessArgs &args) {

    // update the "slow IO" (not audio rate) every 16 samples
    // needs to scale with sample rate somehow
    slowIOPrescaler++;
    if (slowIOPrescaler == 16) {
        slowIOPrescaler = 0;
        updateSlowIO();
        virtualModule.slowConversionCallback();
        virtualModule.ui_dispatch(SENSOR_EVENT_SIG);
        virtualModule.gateseqUI.incrementTimer();
        processTriggerButton();
        updateLEDs();

    }

    // manage the software timers
    virtualModule.sequencer.virtualTimer1Count += virtualModule.sequencer.virtualTimer1Enable;
    virtualModule.sequencer.virtualTimer2Count += virtualModule.sequencer.virtualTimer2Enable;
    virtualModule.sequencer.virtualTimer3Count += virtualModule.sequencer.virtualTimer3Enable;
    virtualModule.sequencer.virtualTimer4Count += virtualModule.sequencer.virtualTimer4Enable;

    if (virtualModule.sequencer.virtualTimer2Count >= virtualModule.sequencer.virtualTimer2Overflow) {
        virtualModule.auxTimer1InterruptCallback();
        virtualModule.sequencer.virtualTimer2Count = 0;
    }
    if (virtualModule.sequencer.virtualTimer3Count >= virtualModule.sequencer.virtualTimer3Overflow) {
        virtualModule.auxTimer2InterruptCallback();
        virtualModule.sequencer.virtualTimer3Count = 0;
    }
    if (virtualModule.sequencer.virtualTimer4Count >= virtualModule.sequencer.virtualTimer4Overflow) {
        virtualModule.auxTimer3InterruptCallback();
        virtualModule.sequencer.virtualTimer4Count = 0;
    }

    acquireCVs();
    processLogicInputs();
    updateOutputs();

    virtualIO->halfTransferCallback();

    float dac1Sample = (float) virtualIO->outputs.dac1Samples[0];
    float dac2Sample = (float) virtualIO->outputs.dac2Samples[0];
    float dac3Sample = (float) virtualIO->outputs.dac3Samples[0];

    // "model" the circuit
    // A and B inputs with normalled reference voltages
    float aIn = inputs[A_INPUT].getVoltage() + (!inputs[A_INPUT].isConnected()) * params[A_PARAM].getValue();
    float bIn = (inputs[B_INPUT].isConnected()) * ((inputs[B_INPUT].getVoltage()) * (params[B_PARAM].getValue())) + (!inputs[B_INPUT].isConnected()) * (5* (params[B_PARAM].getValue()));
    
    // sample and holds
    // get a new sample on the rising edge at the sh control output
    if (virtualIO->shAState > shALast) {
        aSample = aIn;
    }
    if (virtualIO->shBState > shBLast) {
        bSample = bIn;
    }

    shALast = virtualIO->shAState;
    shBLast = virtualIO->shBState;

    // either use the sample or track depending on the sh control output
    aIn = virtualIO->shAState * aSample + !virtualIO->shAState * aIn;
    bIn = virtualIO->shBState * bSample + !virtualIO->shBState * bIn;

    // VCA/mixing stage
    // normalize 12 bits to 0-1
    outputs[MAIN_OUTPUT].setVoltage(bIn*(dac2Sample/4095.0) + aIn*(dac1Sample/4095.0)); 
    outputs[AUX_DAC_OUTPUT].setVoltage((dac3Sample/4095.0 - .5) * -10.666666666);
    outputs[LOGICA_OUTPUT].setVoltage(virtualIO->logicAState * 5.0);
    outputs[AUX_LOGIC_OUTPUT].setVoltage(virtualIO->auxLogicState * 5.0);

    clockDivider = 0;
    
}

struct GateseqWidget : ModuleWidget  {

    GateseqWidget(Gateseq *module) {

        setModule(module);

        box.size = Vec(12 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);

        setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/gateseq.svg")));

        addChild(createWidget(Vec(RACK_GRID_WIDTH, 0)));
        addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
        addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
        addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));

        addParam(createParam(Vec(9.022 + .753, 30.90), module, Gateseq::KNOB1_PARAM));
        addParam(createParam(Vec(68.53 + .753, 30.90), module, Gateseq::KNOB2_PARAM));
        addParam(createParam(Vec(68.53 + .753, 169.89), module, Gateseq::KNOB3_PARAM));
        addParam(createParam(Vec(9.022 + .753, 169.89), module, Gateseq::B_PARAM));
        addParam(createParam(Vec(128.04 + .753, 30.90), module, Gateseq::CV2AMT_PARAM));
        addParam(createParam(Vec(128.04 + .753, 100.4), module, Gateseq::A_PARAM));
        addParam(createParam(Vec(128.04 + .753, 169.89), module, Gateseq::CV3AMT_PARAM));
        
        addParam(createParam(Vec(8 + .753, 85), module, Gateseq::BUTTON1_PARAM));
        addParam(createParam(Vec(48 + .753, 85), module, Gateseq::BUTTON2_PARAM));
        addParam(createParam(Vec(86 + .753, 85), module, Gateseq::BUTTON3_PARAM));
        addParam(createParam(Vec(8 + .753, 139), module, Gateseq::BUTTON4_PARAM));
        addParam(createParam(Vec(48 + .753, 139), module, Gateseq::BUTTON5_PARAM));
        addParam(createParam(Vec(86 + .753, 139), module, Gateseq::BUTTON6_PARAM));
        
        addParam(createParam(Vec(132.7 + .753, 320), module, Gateseq::TRIGBUTTON_PARAM));

        addInput(createInput(Vec(8.07 + 1.053, 241.12), module, Gateseq::A_INPUT));
        addInput(createInput(Vec(8.07 + 1.053, 282.62), module, Gateseq::B_INPUT));
        addInput(createInput(Vec(8.07 + 1.053, 324.02), module, Gateseq::MAIN_LOGIC_INPUT));
        addInput(createInput(Vec(45.75 + 1.053, 241.12), module, Gateseq::CV1_INPUT));
        addInput(createInput(Vec(45.75 + 1.053, 282.62), module, Gateseq::CV2_INPUT));
        addInput(createInput(Vec(45.75 + 1.053, 324.02), module, Gateseq::CV3_INPUT));
        addInput(createInput(Vec(135 + 1.053, 282.62), module, Gateseq::AUX_LOGIC_INPUT));

        addOutput(createOutput(Vec(83.68 + 1.053, 241.12), module, Gateseq::LOGICA_OUTPUT));
        addOutput(createOutput(Vec(83.68 + 1.053, 282.62), module, Gateseq::AUX_DAC_OUTPUT));
        addOutput(createOutput(Vec(83.68 + 1.053, 324.02), module, Gateseq::MAIN_OUTPUT));
        addOutput(createOutput(Vec(135 + 1.053, 241.12), module, Gateseq::AUX_LOGIC_OUTPUT));

        addChild(createLight(Vec(35.8 + .753, 268.5), module, Gateseq::LED1_LIGHT));
        addChild(createLight(Vec(73.7 + .753, 268.5), module, Gateseq::LED2_LIGHT));
        addChild(createLight(Vec(35.8 + .753, 309.9), module, Gateseq::LED3_LIGHT));
        addChild(createLight(Vec(73.7 + .753, 309.9), module, Gateseq::LED4_LIGHT));
        addChild(createLight(Vec(54.8 + .753, 179.6), module, Gateseq::OUTPUT_GREEN_LIGHT));
        addChild(createLight(Vec(59 + .753, 221), module, Gateseq::RED_LIGHT));

        }

    void appendContextMenu(Menu *menu) override {
        Gateseq *module = dynamic_cast(this->module);
        assert(module);

        struct GateseqAux2ModeHandler : MenuItem {
            Gateseq *module;
            int32_t mode;
            void onAction(const event::Action &e) override {
                module->virtualModule.gateseqUI.aux2Mode = mode;
                module->virtualModule.gateseqUI.storeMode(module->virtualModule.gateseqUI.aux2Mode, AUX_MODE2_MASK, AUX_MODE2_SHIFT);
                module->virtualModule.handleAux2ModeChange(mode);
            }
        };

        menu->addChild(new MenuEntry);
        menu->addChild(createMenuLabel("Drum signal out"));
        const std::string logicLabels[] = {
            "And",
            "Or",
            "Xor",
            "Nor"
        };
        for (int i = 0; i < (int) LENGTHOF(logicLabels); i++) {
            GateseqAux2ModeHandler *aux2Item = createMenuItem(logicLabels[i], CHECKMARK(module->virtualModule.gateseqUI.aux2Mode == i));
            aux2Item->module = module;
            aux2Item->mode = i;
            menu->addChild(aux2Item);
        }

        struct PresetRecallItem : MenuItem {
            Gateseq *module;
            int preset;
            void onAction(const event::Action &e) override {
                module->virtualModule.gateseqUI.modeStateBuffer = preset;
                module->virtualModule.gateseqUI.loadFromEEPROM(0);
                module->virtualModule.gateseqUI.recallModuleState();
            }
        };

        struct StockPresetItem : MenuItem {
            Gateseq *module;
            Menu *createChildMenu() override {
                Menu *menu = new Menu();
                const std::string presetLabels[] = {
                    "Euclidean",
                    "2 vs 3",
                    "Shuffle Swing",
                    "Clock Multiplier/Divider",
                    "Logic Processing",
                    "Resample",
                };
                for (int i = 0; i < (int) LENGTHOF(presetLabels); i++) {
                    PresetRecallItem *item = createMenuItem(presetLabels[i], CHECKMARK(module->virtualModule.gateseqUI.modeStateBuffer == (int32_t) module->presetData[i]));
                    item->module = module;
                    item->preset = module->presetData[i];
                    menu->addChild(item);
                }
                return menu;
            }
        };

        menu->addChild(new MenuEntry);
        StockPresetItem *stockPresets = createMenuItem("Stock presets");
        stockPresets->module = module;
        menu->addChild(stockPresets);

        struct ScaleSetHandler : MenuItem {
            Gateseq *module; 
            void onAction(const event::Action &e) override {
             
                char* pathC = osdialog_file(OSDIALOG_OPEN, NULL, NULL, NULL); 
                if (!pathC) { 
                    // Fail silently 
                    return; 
                } 
                DEFER({ 
                    std::free(pathC); 
                }); 
             
                module->virtualModule.readPatternsFromFile(pathC);
                module->virtualModule.handleButton3ModeChange(module->virtualModule.gateseqUI.button3Mode);
                module->virtualModule.handleButton6ModeChange(module->virtualModule.gateseqUI.button6Mode);
                module->patternsPath = pathC;
            }
        };
        ScaleSetHandler *menuItem = createMenuItem("Select Bank Set File");
        menuItem->module = module;
        menu->addChild(menuItem);
        }

};


Model *modelGateseq = createModel("GATESEQ");

// Tooltip definitions

struct Gateseq::PatternIQuantity : ViaKnobQuantity {

    float translateParameter(float value) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        description = "";

        for (uint32_t i = 0; i < gateseqModule->virtualModule.sequencer.aLength; i ++) {
            if (gateseqModule->virtualModule.sequencer.currentAPattern[i]) {
                description += "^";
            } else {
                description += "~";
            }
        }

        return 1 + (gateseqModule->virtualModule.controls.knob1Value >> 8);            
    
    }
    float translateInput(float userInput) override {

        return (userInput - 1) * 256.0;

    };

};

struct Gateseq::PatternIModQuantity : ViaKnobQuantity {

    std::string labels[3] = {"Pattern I offset", "Pattern I shuffle/swing", "Pattern I multiplier"};

    float multiplierLookup[8] = {0.5, 1, 1.5, 2, 3, 4, 6, 8};

    float translateParameter(float value) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        if (gateseqModule->virtualModule.sequencer.modulateMultiplier) {

            int multIndex = gateseqModule->virtualModule.controls.knob2Value >> 9;
            return (gateseqModule->virtualModule.sequencer.multipliers[multIndex]) * 0.5;

        } else if (gateseqModule->virtualModule.sequencer.shuffleOn) {
            int swing = gateseqModule->virtualModule.controls.knob2Value virtualModule.controls.knob2Value >> 9;
        }            
    
    }
    float translateInput(float userInput) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        if (gateseqModule->virtualModule.sequencer.modulateMultiplier) {
            for (int i = 0; i < 8; i++) {
                if (userInput == multiplierLookup[i]) {
                    return i * 512.0;
                }
            }

            return getValue();

        } else if (gateseqModule->virtualModule.sequencer.shuffleOn) {
            return (userInput - 25.0) * 4095.0/50.0;
        } else {
            return userInput * 512.0;
        }

    };
    void setLabel(void) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        if (gateseqModule->virtualModule.sequencer.modulateMultiplier) {
            name = labels[2];
            unit = "x";
        } else if (gateseqModule->virtualModule.sequencer.shuffleOn) {
            name = labels[1];
            unit = "%";
        } else {
            name = labels[0];
            unit = " steps";
        }

    }
    int getDisplayPrecision(void) override {
        return 2;
    }

    std::string getDisplayValueString(void) override {

        std::string displayValueRaw = string::f("%.*g", getDisplayPrecision(), math::normalizeZero(getDisplayValue()));

        return displayValueRaw;

    }

};

struct Gateseq::PatternIIQuantity : ViaKnobQuantity {

    float translateParameter(float value) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        description = "";

        for (uint32_t i = 0; i < gateseqModule->virtualModule.sequencer.bLength; i ++) {
            if (gateseqModule->virtualModule.sequencer.currentBPattern[i]) {
                description += "^";
            } else {
                description += "~";
            }
        }

        return 1 + (gateseqModule->virtualModule.controls.knob3Value >> 8);            
    
    }
    float translateInput(float userInput) override {

        return (userInput - .5)  * 256.0;

    };

};

struct Gateseq::SHIButtonQuantity : ViaButtonQuantity {

    std::string buttonModes[3] = {"Off", "Sample and hold during gate", "Resample on rising edge"};

    SHIButtonQuantity() {
        for (int i = 0; i < 3; i++) {
            modes[i] = buttonModes[i];
        }
    }
    
    int getModeEnumeration(void) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        return gateseqModule->virtualModule.gateseqUI.button1Mode;

    }

    void setMode(int mode) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        gateseqModule->virtualModule.gateseqUI.button1Mode = mode;
        gateseqModule->virtualModule.gateseqUI.storeMode(gateseqModule->virtualModule.gateseqUI.button1Mode, BUTTON1_MASK, BUTTON1_SHIFT);
        gateseqModule->virtualModule.handleButton1ModeChange(mode);

    }

};

struct Gateseq::GateIButtonQuantity : ViaButtonQuantity {

    std::string buttonModes[3] = {"Open", "Gated", "Smooth Gate"};

    GateIButtonQuantity() {
        for (int i = 0; i < 3; i++) {
            modes[i] = buttonModes[i];
        }
    }
    
    int getModeEnumeration(void) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        return gateseqModule->virtualModule.gateseqUI.button2Mode;

    }

    void setMode(int mode) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        gateseqModule->virtualModule.gateseqUI.button2Mode = mode;
        gateseqModule->virtualModule.gateseqUI.storeMode(gateseqModule->virtualModule.gateseqUI.button2Mode, BUTTON2_MASK, BUTTON2_SHIFT);
        gateseqModule->virtualModule.handleButton2ModeChange(mode);

    }

};

struct Gateseq::SeqIButtonQuantity : ViaButtonQuantity {

    std::string buttonModes[4] = {"Length 16 Euclidean", "3 vs 2", "Shuffle-Swing", "Multiplier/Divider"};

    SeqIButtonQuantity() {
        for (int i = 0; i < 4; i++) {
            modes[i] = buttonModes[i];
        }
    }
    
    int getModeEnumeration(void) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        return gateseqModule->virtualModule.gateseqUI.button3Mode;

    }

    void setMode(int mode) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        gateseqModule->virtualModule.gateseqUI.button3Mode = mode;
        gateseqModule->virtualModule.gateseqUI.storeMode(gateseqModule->virtualModule.gateseqUI.button3Mode, BUTTON3_MASK, BUTTON3_SHIFT);
        gateseqModule->virtualModule.handleButton3ModeChange(mode);

    }

};

struct Gateseq::SHIIButtonQuantity : ViaButtonQuantity {

    std::string buttonModes[3] = {"Off", "Sample and hold during gate", "Resample on rising edge"};
    
    SHIIButtonQuantity() {
        for (int i = 0; i < 3; i++) {
            modes[i] = buttonModes[i];
        }
    }
    
    int getModeEnumeration(void) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        return gateseqModule->virtualModule.gateseqUI.button4Mode;

    }

    void setMode(int mode) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        gateseqModule->virtualModule.gateseqUI.button4Mode = mode;
        gateseqModule->virtualModule.gateseqUI.storeMode(gateseqModule->virtualModule.gateseqUI.button4Mode, BUTTON4_MASK, BUTTON4_SHIFT);
        gateseqModule->virtualModule.handleButton4ModeChange(mode);

    }

};

struct Gateseq::GateIIButtonQuantity : ViaButtonQuantity {

    std::string buttonModes[3] = {"Open", "Gated", "Smooth Gate"};

    GateIIButtonQuantity() {
        for (int i = 0; i < 3; i++) {
            modes[i] = buttonModes[i];
        }
    }
    
    int getModeEnumeration(void) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        return gateseqModule->virtualModule.gateseqUI.button5Mode;

    }

    void setMode(int mode) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        gateseqModule->virtualModule.gateseqUI.button5Mode = mode;
        gateseqModule->virtualModule.gateseqUI.storeMode(gateseqModule->virtualModule.gateseqUI.button5Mode, BUTTON5_MASK, BUTTON5_SHIFT);
        gateseqModule->virtualModule.handleButton5ModeChange(mode);

    }

};

struct Gateseq::SeqIIButtonQuantity : ViaButtonQuantity {

    std::string buttonModes[4] = {"Length 16 Euclidean", "Odd vs Even", "2 or 3 Gates", "Rhythmic Clock Division"};

    SeqIIButtonQuantity() {
        for (int i = 0; i < 4; i++) {
            modes[i] = buttonModes[i];
        }
    }
    
    int getModeEnumeration(void) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        return gateseqModule->virtualModule.gateseqUI.button6Mode;

    }

    void setMode(int mode) override {

        Gateseq * gateseqModule = dynamic_cast(this->module);

        gateseqModule->virtualModule.gateseqUI.button6Mode = mode;
        gateseqModule->virtualModule.gateseqUI.storeMode(gateseqModule->virtualModule.gateseqUI.button6Mode, BUTTON6_MASK, BUTTON6_SHIFT);
        gateseqModule->virtualModule.handleButton6ModeChange(mode);

    }

};

struct Gateseq::ModulationQuantity : ParamQuantity {

    std::string modes[4] = {"Offset", "Offset", "Shuffle to Swing", "Multiplier"};

    std::string getDisplayValueString() override {

        Gateseq * gateseqModule = (Gateseq *) module;

        return modes[gateseqModule->virtualModule.gateseqUI.button3Mode];                

    }

    std::string getString() override {
        return getDisplayValueString();
    }

};

struct Gateseq::ModulationCVQuantity : ParamQuantity {

    std::string modes[4] = {"(Offset)", "(Offset)", "(Shufle to Swing)", "(Multiplier)"};

    std::string getDisplayValueString() override {

        Gateseq * gateseqModule = (Gateseq *) module;

        return "PTN I Modulation CV Attenuator " + modes[gateseqModule->virtualModule.gateseqUI.button3Mode];

    }

    std::string getString() override {
        return getDisplayValueString();
    }

};

struct Gateseq::ButtonQuantity : ParamQuantity {

    std::string getString() override {
        return "Manual reset";
    }

};

Web Proxy Viewer  |  New URL  |  Original Page