|
- #pragma once
- #include "common.hpp"
- #include "string.hpp"
- #include "plugin/Model.hpp"
- #include "engine/Param.hpp"
- #include "engine/Port.hpp"
- #include "engine/Light.hpp"
- #include "engine/ParamQuantity.hpp"
- #include <vector>
- #include <jansson.h>
-
-
- namespace rack {
-
-
- namespace plugin {
- struct Model;
- }
-
-
- namespace engine {
-
-
- /** DSP processor instance for your module. */
- struct Module {
- plugin::Model *model = NULL; /** Unique ID for referring to the module in the engine.
- Assigned when added to the engine.
- */
- int id = -1;
-
- /** Arrays of components.
- Initialized with config().
- */
- std::vector<Param> params;
- std::vector<Output> outputs;
- std::vector<Input> inputs;
- std::vector<Light> lights;
- std::vector<ParamQuantity*> paramQuantities;
-
- /** ID of the Module immediately to the left, or -1 if nonexistent. */
- int leftModuleId = -1;
- /** Pointer to the left Module, or NULL if nonexistent. */
- Module *leftModule = NULL;
- /** Double buffer for receiving messages from adjacent modules.
- If this module receives messages from adjacent modules, allocate both message buffers with identical blocks of memory (arrays, structs, etc).
- Remember to free the buffer in the Module destructor.
- Example:
-
- leftProducerMessage = new MyModuleMessage;
- leftConsumerMessage = new MyModuleMessage;
-
- At the end of each timestep, the buffers are flipped/swapped.
-
- You may choose for the Module to write to its own message buffer for consumption by other modules.
- As long as this convention is followed by the left Module, this is fine.
- */
- void *leftProducerMessage = NULL;
- void *leftConsumerMessage = NULL;
-
- int rightModuleId = -1;
- Module *rightModule = NULL;
- void *rightProducerMessage = NULL;
- void *rightConsumerMessage = NULL;
-
- /** Seconds spent in the process() method, with exponential smoothing.
- Only written when CPU timing is enabled, since time measurement is expensive.
- */
- float cpuTime = 0.f;
- /** Whether the Module is skipped from stepping by the engine.
- Module subclasses should not read/write this variable.
- */
- bool bypass = false;
-
- /** Constructs a Module with no params, inputs, outputs, and lights. */
- Module();
- /** Use config() instead. */
- DEPRECATED Module(int numParams, int numInputs, int numOutputs, int numLights = 0) : Module() {
- config(numParams, numInputs, numOutputs, numLights);
- }
- virtual ~Module();
-
- /** Configures the number of Params, Outputs, Inputs, and Lights. */
- void config(int numParams, int numInputs, int numOutputs, int numLights = 0);
-
- template <class TParamQuantity = ParamQuantity>
- void configParam(int paramId, float minValue, float maxValue, float defaultValue, std::string label = "", std::string unit = "", float displayBase = 0.f, float displayMultiplier = 1.f, float displayOffset = 0.f) {
- assert(paramId < (int) params.size() && paramId < (int) paramQuantities.size());
- if (paramQuantities[paramId])
- delete paramQuantities[paramId];
-
- Param *p = ¶ms[paramId];
- p->value = defaultValue;
-
- ParamQuantity *q = new TParamQuantity;
- q->module = this;
- q->paramId = paramId;
- q->minValue = minValue;
- q->maxValue = maxValue;
- q->defaultValue = defaultValue;
- if (!label.empty())
- q->label = label;
- else
- q->label = string::f("#%d", paramId + 1);
- q->unit = unit;
- q->displayBase = displayBase;
- q->displayMultiplier = displayMultiplier;
- q->displayOffset = displayOffset;
- paramQuantities[paramId] = q;
- }
-
- struct ProcessArgs {
- float sampleRate;
- float sampleTime;
- };
-
- /** Advances the module by one audio sample.
- Override this method to read Inputs and Params and to write Outputs and Lights.
- */
- virtual void process(const ProcessArgs &args) {
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- step();
- #pragma GCC diagnostic pop
- }
- /** Override process(const ProcessArgs &args) instead. */
- DEPRECATED virtual void step() {}
-
- /** Called when the engine sample rate is changed. */
- virtual void onSampleRateChange() {}
- /** Called when user clicks Initialize in the module context menu. */
- virtual void onReset() {}
- /** Called when user clicks Randomize in the module context menu. */
- virtual void onRandomize() {}
- /** Called when the Module is added to the Engine */
- virtual void onAdd() {}
- /** Called when the Module is removed from the Engine */
- virtual void onRemove() {}
-
- json_t *toJson();
- void fromJson(json_t *rootJ);
-
- /** Override to store extra internal data in the "data" property of the module's JSON object. */
- virtual json_t *dataToJson() { return NULL; }
- virtual void dataFromJson(json_t *root) {}
- };
-
-
- } // namespace engine
- } // namespace rack
|