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.

Module.hpp 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #pragma once
  2. #include <common.hpp>
  3. #include <string.hpp>
  4. #include <plugin/Model.hpp>
  5. #include <engine/Param.hpp>
  6. #include <engine/Port.hpp>
  7. #include <engine/Light.hpp>
  8. #include <engine/ParamQuantity.hpp>
  9. #include <engine/PortInfo.hpp>
  10. #include <vector>
  11. #include <jansson.h>
  12. namespace rack {
  13. namespace plugin {
  14. struct Model;
  15. }
  16. namespace engine {
  17. /** DSP processor instance for your module. */
  18. struct Module {
  19. plugin::Model* model = NULL;
  20. /** Unique ID for referring to the module in the engine.
  21. Assigned when added to the engine.
  22. */
  23. int id = -1;
  24. /** Arrays of components.
  25. Initialized with config().
  26. */
  27. std::vector<Param> params;
  28. std::vector<Input> inputs;
  29. std::vector<Output> outputs;
  30. std::vector<Light> lights;
  31. std::vector<ParamQuantity*> paramQuantities;
  32. std::vector<PortInfo*> inputInfos;
  33. std::vector<PortInfo*> outputInfos;
  34. /** Represents a message-passing channel for an adjacent module. */
  35. struct Expander {
  36. /** ID of the expander module, or -1 if nonexistent. */
  37. int moduleId = -1;
  38. /** Pointer to the expander Module, or NULL if nonexistent. */
  39. Module* module = NULL;
  40. /** Double buffer for receiving messages from the expander module.
  41. If you intend to receive messages from an expander, allocate both message buffers with identical blocks of memory (arrays, structs, etc).
  42. Remember to free the buffer in the Module destructor.
  43. Example:
  44. rightExpander.producerMessage = new MyExpanderMessage;
  45. rightExpander.consumerMessage = new MyExpanderMessage;
  46. You must check the expander module's `model` before attempting to write its message buffer.
  47. Once the module is checked, you can reinterpret_cast its producerMessage at no performance cost.
  48. Producer messages are intended to be write-only.
  49. Consumer messages are intended to be read-only.
  50. Once you write a message, set messageFlipRequested to true to request that the messages are flipped at the end of the timestep.
  51. This means that message-passing has 1-sample latency.
  52. You may choose for your Module to instead write to its own message buffer for consumption by other modules, i.e. the expander "pulls" rather than this module "pushing".
  53. As long as this convention is followed by the other module, this is fine.
  54. */
  55. void* producerMessage = NULL;
  56. void* consumerMessage = NULL;
  57. bool messageFlipRequested = false;
  58. };
  59. Expander leftExpander;
  60. Expander rightExpander;
  61. /** Seconds spent in the process() method, with exponential smoothing.
  62. Only written when CPU timing is enabled, since time measurement is expensive.
  63. */
  64. float cpuTime = 0.f;
  65. /** Whether the Module is skipped from stepping by the engine.
  66. Module subclasses should not read/write this variable.
  67. */
  68. bool disabled = false;
  69. /** Constructs a Module with no params, inputs, outputs, and lights. */
  70. Module();
  71. /** Use config() instead. */
  72. DEPRECATED Module(int numParams, int numInputs, int numOutputs, int numLights = 0) : Module() {
  73. config(numParams, numInputs, numOutputs, numLights);
  74. }
  75. virtual ~Module();
  76. /** Configures the number of Params, Outputs, Inputs, and Lights. */
  77. void config(int numParams, int numInputs, int numOutputs, int numLights = 0);
  78. template <class TParamQuantity = ParamQuantity>
  79. void configParam(int paramId, float minValue, float maxValue, float defaultValue, std::string name = "", std::string unit = "", float displayBase = 0.f, float displayMultiplier = 1.f, float displayOffset = 0.f) {
  80. assert(paramId < (int) params.size() && paramId < (int) paramQuantities.size());
  81. if (paramQuantities[paramId])
  82. delete paramQuantities[paramId];
  83. Param* p = &params[paramId];
  84. p->value = defaultValue;
  85. ParamQuantity* q = new TParamQuantity;
  86. q->module = this;
  87. q->paramId = paramId;
  88. q->minValue = minValue;
  89. q->maxValue = maxValue;
  90. q->defaultValue = defaultValue;
  91. q->name = name;
  92. q->unit = unit;
  93. q->displayBase = displayBase;
  94. q->displayMultiplier = displayMultiplier;
  95. q->displayOffset = displayOffset;
  96. paramQuantities[paramId] = q;
  97. }
  98. template <class TPortInfo = PortInfo>
  99. void configInput(int portId, std::string name = "") {
  100. assert(portId < (int) inputs.size() && portId < (int) inputInfos.size());
  101. if (inputInfos[portId])
  102. delete inputInfos[portId];
  103. PortInfo* p = new TPortInfo;
  104. p->module = this;
  105. p->type = Port::INPUT;
  106. p->portId = portId;
  107. p->name = name;
  108. inputInfos[portId] = p;
  109. }
  110. template <class TPortInfo = PortInfo>
  111. void configOutput(int portId, std::string name = "") {
  112. assert(portId < (int) outputs.size() && portId < (int) outputInfos.size());
  113. if (outputInfos[portId])
  114. delete outputInfos[portId];
  115. PortInfo* p = new TPortInfo;
  116. p->module = this;
  117. p->type = Port::OUTPUT;
  118. p->portId = portId;
  119. p->name = name;
  120. outputInfos[portId] = p;
  121. }
  122. struct ProcessArgs {
  123. float sampleRate;
  124. float sampleTime;
  125. };
  126. /** Advances the module by one audio sample.
  127. Override this method to read Inputs and Params and to write Outputs and Lights.
  128. */
  129. virtual void process(const ProcessArgs& args) {
  130. step();
  131. }
  132. /** DEPRECATED. Override `process(const ProcessArgs& args)` instead. */
  133. virtual void step() {}
  134. json_t* toJson();
  135. /** This is virtual only for the purpose of unserializing legacy data when you could set properties of the `.modules[]` object itself.
  136. Normally you should override dataFromJson().
  137. Remember to call `Module::fromJson(rootJ)` within your overridden method.
  138. */
  139. virtual void fromJson(json_t* rootJ);
  140. /** Override to store extra internal data in the "data" property of the module's JSON object. */
  141. virtual json_t* dataToJson() {
  142. return NULL;
  143. }
  144. virtual void dataFromJson(json_t* root) {}
  145. ///////////////////////
  146. // Events
  147. ///////////////////////
  148. // All of these events are thread-safe with process().
  149. struct AddEvent {};
  150. /** Called after adding the module to the Engine.
  151. */
  152. virtual void onAdd(const AddEvent& e) {
  153. // Call deprecated event method by default
  154. onAdd();
  155. }
  156. struct RemoveEvent {};
  157. /** Called before removing the module to the Engine.
  158. */
  159. virtual void onRemove(const RemoveEvent& e) {
  160. // Call deprecated event method by default
  161. onRemove();
  162. }
  163. struct EnableEvent {};
  164. /** Called after enabling the module.
  165. */
  166. virtual void onEnable(const EnableEvent& e) {}
  167. struct DisableEvent {};
  168. /** Called after disabling the module.
  169. */
  170. virtual void onDisable(const DisableEvent& e) {}
  171. struct PortChangeEvent {
  172. /** True if connecting, false if disconnecting. */
  173. bool connecting;
  174. Port::Type type;
  175. int portId;
  176. };
  177. /** Called after a cable connects to or disconnects from a port.
  178. This event is not called for output ports if a stackable cable was added/removed and did not change the port's connected state.
  179. */
  180. virtual void onPortChange(const PortChangeEvent& e) {}
  181. struct SampleRateChangeEvent {
  182. float sampleRate;
  183. float sampleTime;
  184. };
  185. /** Called after the Engine sample rate changes.
  186. */
  187. virtual void onSampleRateChange(const SampleRateChangeEvent& e) {
  188. // Call deprecated event method by default
  189. onSampleRateChange();
  190. }
  191. struct ExpanderChangeEvent {};
  192. /** Called after the Engine sample rate changes.
  193. */
  194. virtual void onExpanderChange(const ExpanderChangeEvent& e) {}
  195. struct ResetEvent {};
  196. /** Called when the user resets (initializes) the module.
  197. The default implementation resets all parameters to their default value, so you must call `Module::onRandomize(e)` if you want to keep this behavior.
  198. */
  199. virtual void onReset(const ResetEvent& e);
  200. struct RandomizeEvent {};
  201. /** Called when the user randomizes the module.
  202. The default implementation randomizes all parameters by default, so you must call `Module::onRandomize(e)` if you want to keep this behavior.
  203. */
  204. virtual void onRandomize(const RandomizeEvent& e);
  205. /** DEPRECATED. Override `onAdd(e)` instead. */
  206. virtual void onAdd() {}
  207. /** DEPRECATED. Override `onRemove(e)` instead. */
  208. virtual void onRemove() {}
  209. /** DEPRECATED. Override `onReset(e)` instead. */
  210. virtual void onReset() {}
  211. /** DEPRECATED. Override `onRandomize(e)` instead. */
  212. virtual void onRandomize() {}
  213. /** DEPRECATED. Override `onSampleRateChange(e)` instead. */
  214. virtual void onSampleRateChange() {}
  215. };
  216. } // namespace engine
  217. } // namespace rack