#include "Template.hpp" namespace rack_plugin_Template { struct MyModule : Module { enum ParamIds { PITCH_PARAM, NUM_PARAMS }; enum InputIds { PITCH_INPUT, NUM_INPUTS }; enum OutputIds { SINE_OUTPUT, NUM_OUTPUTS }; enum LightIds { BLINK_LIGHT, NUM_LIGHTS }; float phase = 0.0; float blinkPhase = 0.0; MyModule() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} void step() override; // For more advanced Module features, read Rack's engine.hpp header file // - toJson, fromJson: serialization of internal data // - 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 MyModule::step() { // Implement a simple sine oscillator float deltaTime = engineGetSampleTime(); // Compute the frequency from the pitch parameter and input float pitch = params[PITCH_PARAM].value; pitch += inputs[PITCH_INPUT].value; pitch = clamp(pitch, -4.0f, 4.0f); // The default pitch is C4 float freq = 261.626f * powf(2.0f, pitch); // Accumulate the phase phase += freq * deltaTime; if (phase >= 1.0f) phase -= 1.0f; // Compute the sine output float sine = sinf(2.0f * M_PI * phase); outputs[SINE_OUTPUT].value = 5.0f * sine; // Blink light at 1Hz blinkPhase += deltaTime; if (blinkPhase >= 1.0f) blinkPhase -= 1.0f; lights[BLINK_LIGHT].value = (blinkPhase < 0.5f) ? 1.0f : 0.0f; } struct MyModuleWidget : ModuleWidget { MyModuleWidget(MyModule *module) : ModuleWidget(module) { setPanel(SVG::load(assetPlugin(plugin, "res/MyModule.svg"))); addChild(Widget::create(Vec(RACK_GRID_WIDTH, 0))); addChild(Widget::create(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0))); addChild(Widget::create(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); addChild(Widget::create(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); addParam(ParamWidget::create(Vec(28, 87), module, MyModule::PITCH_PARAM, -3.0, 3.0, 0.0)); addInput(Port::create(Vec(33, 186), Port::INPUT, module, MyModule::PITCH_INPUT)); addOutput(Port::create(Vec(33, 275), Port::OUTPUT, module, MyModule::SINE_OUTPUT)); addChild(ModuleLightWidget::create>(Vec(41, 59), module, MyModule::BLINK_LIGHT)); } }; } // namespace rack_plugin_Template using namespace rack_plugin_Template; // 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. RACK_PLUGIN_MODEL_INIT(Template, MyModule) { Model *modelMyModule = Model::create("Template", "MyModule", "My Module", OSCILLATOR_TAG); return modelMyModule; }