You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.9KB

  1. #include "Template.hpp"
  2. namespace rack_plugin_Template {
  3. struct MyModule : Module {
  4. enum ParamIds {
  5. PITCH_PARAM,
  6. NUM_PARAMS
  7. };
  8. enum InputIds {
  9. PITCH_INPUT,
  10. NUM_INPUTS
  11. };
  12. enum OutputIds {
  13. SINE_OUTPUT,
  14. NUM_OUTPUTS
  15. };
  16. enum LightIds {
  17. BLINK_LIGHT,
  18. NUM_LIGHTS
  19. };
  20. float phase = 0.0;
  21. float blinkPhase = 0.0;
  22. MyModule() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  23. void step() override;
  24. // For more advanced Module features, read Rack's engine.hpp header file
  25. // - toJson, fromJson: serialization of internal data
  26. // - onSampleRateChange: event triggered by a change of sample rate
  27. // - onReset, onRandomize, onCreate, onDelete: implements special behavior when user clicks these from the context menu
  28. };
  29. void MyModule::step() {
  30. // Implement a simple sine oscillator
  31. float deltaTime = engineGetSampleTime();
  32. // Compute the frequency from the pitch parameter and input
  33. float pitch = params[PITCH_PARAM].value;
  34. pitch += inputs[PITCH_INPUT].value;
  35. pitch = clamp(pitch, -4.0f, 4.0f);
  36. // The default pitch is C4
  37. float freq = 261.626f * powf(2.0f, pitch);
  38. // Accumulate the phase
  39. phase += freq * deltaTime;
  40. if (phase >= 1.0f)
  41. phase -= 1.0f;
  42. // Compute the sine output
  43. float sine = sinf(2.0f * M_PI * phase);
  44. outputs[SINE_OUTPUT].value = 5.0f * sine;
  45. // Blink light at 1Hz
  46. blinkPhase += deltaTime;
  47. if (blinkPhase >= 1.0f)
  48. blinkPhase -= 1.0f;
  49. lights[BLINK_LIGHT].value = (blinkPhase < 0.5f) ? 1.0f : 0.0f;
  50. }
  51. struct MyModuleWidget : ModuleWidget {
  52. MyModuleWidget(MyModule *module) : ModuleWidget(module) {
  53. setPanel(SVG::load(assetPlugin(plugin, "res/MyModule.svg")));
  54. addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  55. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  56. addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  57. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  58. addParam(ParamWidget::create<Davies1900hBlackKnob>(Vec(28, 87), module, MyModule::PITCH_PARAM, -3.0, 3.0, 0.0));
  59. addInput(Port::create<PJ301MPort>(Vec(33, 186), Port::INPUT, module, MyModule::PITCH_INPUT));
  60. addOutput(Port::create<PJ301MPort>(Vec(33, 275), Port::OUTPUT, module, MyModule::SINE_OUTPUT));
  61. addChild(ModuleLightWidget::create<MediumLight<RedLight>>(Vec(41, 59), module, MyModule::BLINK_LIGHT));
  62. }
  63. };
  64. } // namespace rack_plugin_Template
  65. using namespace rack_plugin_Template;
  66. // Specify the Module and ModuleWidget subclass, human-readable
  67. // author name for categorization per plugin, module slug (should never
  68. // change), human-readable module name, and any number of tags
  69. // (found in `include/tags.hpp`) separated by commas.
  70. RACK_PLUGIN_MODEL_INIT(Template, MyModule) {
  71. Model *modelMyModule = Model::create<MyModule, MyModuleWidget>("Template", "MyModule", "My Module", OSCILLATOR_TAG);
  72. return modelMyModule;
  73. }