Walk.cpp (5884B)
1 2 #include "Walk.hpp" 3 4 #define POLY_INPUT "poly_input" 5 #define JUMP_MODE "jump_mode" 6 #define JUMP_MODE_JUMP "jump" 7 #define JUMP_MODE_TRACKHOLD "track_and_hold" 8 #define JUMP_MODE_SAMPLEHOLD "sample_and_hold" 9 10 void Walk::reset() { 11 for (int i = 0; i < maxChannels; ++i) { 12 _jumpTrigger[i].reset(); 13 } 14 } 15 16 void Walk::sampleRateChange() { 17 for (int i = 0; i < maxChannels; ++i) { 18 _slew[i].setParams(APP->engine->getSampleRate(), 100.0f, 10.0f); 19 } 20 } 21 22 json_t* Walk::saveToJson(json_t* root) { 23 json_object_set_new(root, POLY_INPUT, json_integer(_polyInputID)); 24 switch (_jumpMode) { 25 case JUMP_JUMPMODE: { 26 json_object_set_new(root, JUMP_MODE, json_string(JUMP_MODE_JUMP)); 27 break; 28 } 29 case TRACKHOLD_JUMPMODE: { 30 json_object_set_new(root, JUMP_MODE, json_string(JUMP_MODE_TRACKHOLD)); 31 break; 32 } 33 case SAMPLEHOLD_JUMPMODE: { 34 json_object_set_new(root, JUMP_MODE, json_string(JUMP_MODE_SAMPLEHOLD)); 35 break; 36 } 37 } 38 return root; 39 } 40 41 void Walk::loadFromJson(json_t* root) { 42 json_t* p = json_object_get(root, POLY_INPUT); 43 if (p) { 44 _polyInputID = json_integer_value(p); 45 } 46 47 json_t* jm = json_object_get(root, JUMP_MODE); 48 if (jm) { 49 if (strcmp(json_string_value(jm), JUMP_MODE_JUMP) == 0) { 50 _jumpMode = JUMP_JUMPMODE; 51 } 52 else if (strcmp(json_string_value(jm), JUMP_MODE_TRACKHOLD) == 0) { 53 _jumpMode = TRACKHOLD_JUMPMODE; 54 } 55 else if (strcmp(json_string_value(jm), JUMP_MODE_SAMPLEHOLD) == 0) { 56 _jumpMode = SAMPLEHOLD_JUMPMODE; 57 } 58 } 59 } 60 61 int Walk::channels() { 62 int id = _polyInputID; 63 if (!(_polyInputID == OFFSET_INPUT || _polyInputID == SCALE_INPUT || _polyInputID == JUMP_INPUT)) { 64 id = RATE_INPUT; 65 } 66 return inputs[id].getChannels(); 67 } 68 69 void Walk::modulateChannel(int c) { 70 float rate = params[RATE_PARAM].getValue(); 71 if (inputs[RATE_INPUT].isConnected()) { 72 rate *= clamp(inputs[RATE_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); 73 } 74 rate = 0.2f * powf(rate, 5.0f); 75 _walk[c].setParams(APP->engine->getSampleRate(), rate); 76 77 _offset[c] = params[OFFSET_PARAM].getValue(); 78 if (inputs[OFFSET_INPUT].isConnected()) { 79 _offset[c] *= clamp(inputs[OFFSET_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); 80 } 81 _offset[c] *= 5.0f; 82 83 _scale[c] = params[SCALE_PARAM].getValue(); 84 if (inputs[SCALE_INPUT].isConnected()) { 85 _scale[c] *= clamp(inputs[SCALE_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); 86 } 87 } 88 89 void Walk::processChannel(const ProcessArgs& args, int c) { 90 float triggered = _jumpTrigger[c].process(inputs[JUMP_INPUT].getPolyVoltage(c)); 91 float out = _walk[c].next(); 92 93 switch (_jumpMode) { 94 case JUMP_JUMPMODE: { 95 if (triggered) { 96 _walk[c].jump(); 97 } 98 break; 99 } 100 case TRACKHOLD_JUMPMODE: { 101 if (_jumpTrigger[c].isHigh()) { 102 _lastOut[c] = out; 103 } 104 else { 105 out = _lastOut[c]; 106 } 107 break; 108 } 109 case SAMPLEHOLD_JUMPMODE: { 110 if (triggered) { 111 _lastOut[c] = out; 112 } 113 else { 114 out = _lastOut[c]; 115 } 116 break; 117 } 118 } 119 120 out = _slew[c].next(out); 121 out *= _scale[c]; 122 out += _offset[c]; 123 124 outputs[OUT_OUTPUT].setChannels(_channels); 125 outputs[OUT_OUTPUT].setVoltage(out, c); 126 } 127 128 struct WalkWidget : BGModuleWidget { 129 static constexpr int hp = 3; 130 131 WalkWidget(Walk* module) { 132 setModule(module); 133 box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT); 134 setPanel(box.size, "Walk"); 135 createScrews(); 136 137 // generated by svg_widgets.rb 138 auto rateParamPosition = Vec(8.0, 36.5); 139 auto offsetParamPosition = Vec(14.5, 91.0); 140 auto scaleParamPosition = Vec(14.5, 130.0); 141 142 auto rateInputPosition = Vec(10.5, 160.0); 143 auto offsetInputPosition = Vec(10.5, 195.0); 144 auto scaleInputPosition = Vec(10.5, 230.0); 145 auto jumpInputPosition = Vec(10.5, 265.0); 146 147 auto outOutputPosition = Vec(10.5, 303.0); 148 // end generated by svg_widgets.rb 149 150 addParam(createParam<Knob29>(rateParamPosition, module, Walk::RATE_PARAM)); 151 addParam(createParam<Knob16>(offsetParamPosition, module, Walk::OFFSET_PARAM)); 152 addParam(createParam<Knob16>(scaleParamPosition, module, Walk::SCALE_PARAM)); 153 154 addInput(createInput<Port24>(rateInputPosition, module, Walk::RATE_INPUT)); 155 addInput(createInput<Port24>(offsetInputPosition, module, Walk::OFFSET_INPUT)); 156 addInput(createInput<Port24>(scaleInputPosition, module, Walk::SCALE_INPUT)); 157 addInput(createInput<Port24>(jumpInputPosition, module, Walk::JUMP_INPUT)); 158 159 addOutput(createOutput<Port24>(outOutputPosition, module, Walk::OUT_OUTPUT)); 160 } 161 162 void contextMenu(Menu* menu) override { 163 auto m = dynamic_cast<Walk*>(module); 164 assert(m); 165 166 OptionsMenuItem* p = new OptionsMenuItem("Polyphony channels from"); 167 p->addItem(OptionMenuItem("RATE input", [m]() { return m->_polyInputID == Walk::RATE_INPUT; }, [m]() { m->_polyInputID = Walk::RATE_INPUT; })); 168 p->addItem(OptionMenuItem("OFFSET input", [m]() { return m->_polyInputID == Walk::OFFSET_INPUT; }, [m]() { m->_polyInputID = Walk::OFFSET_INPUT; })); 169 p->addItem(OptionMenuItem("SCALE input", [m]() { return m->_polyInputID == Walk::SCALE_INPUT; }, [m]() { m->_polyInputID = Walk::SCALE_INPUT; })); 170 p->addItem(OptionMenuItem("JUMP input", [m]() { return m->_polyInputID == Walk::JUMP_INPUT; }, [m]() { m->_polyInputID = Walk::JUMP_INPUT; })); 171 OptionsMenuItem::addToMenu(p, menu); 172 173 OptionsMenuItem* jm = new OptionsMenuItem("Jump input action"); 174 jm->addItem(OptionMenuItem("Jump", [m]() { return m->_jumpMode == Walk::JUMP_JUMPMODE; }, [m]() { m->_jumpMode = Walk::JUMP_JUMPMODE; })); 175 jm->addItem(OptionMenuItem("Sample and hold", [m]() { return m->_jumpMode == Walk::SAMPLEHOLD_JUMPMODE; }, [m]() { m->_jumpMode = Walk::SAMPLEHOLD_JUMPMODE; })); 176 jm->addItem(OptionMenuItem("Track and hold", [m]() { return m->_jumpMode == Walk::TRACKHOLD_JUMPMODE; }, [m]() { m->_jumpMode = Walk::TRACKHOLD_JUMPMODE; })); 177 OptionsMenuItem::addToMenu(jm, menu); 178 } 179 }; 180 181 Model* modelWalk = bogaudio::createModel<Walk, WalkWidget>("Bogaudio-Walk", "WALK", "Random-walk CV source", "Random", "Sample and hold", "Polyphonic");