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.

91 lines
3.0KB

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