|
- /*
- * DISTRHO Cardinal Plugin
- * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * For a full copy of the GNU General Public License see the LICENSE file.
- */
-
- /**
- * This file contains a substantial amount of code from VCVRack, adjusted for inline use
- * Copyright (C) 2016-2021 VCV.
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- */
-
- #pragma once
-
- #include <cmath>
- #include <cstdlib>
- #include <cstring>
-
- #include <algorithm>
- #include <list>
- #include <memory>
- #include <string>
- #include <vector>
-
- struct NVGcolor { float a; };
- struct NVGpaint {};
-
- inline NVGcolor nvgRGB(int r, int g, int b) { return {}; }
- inline NVGcolor nvgRGBA(int r, int g, int b, int a) { return {}; }
- inline NVGcolor nvgRGBf(float r, float g, float b) { return {}; }
- inline NVGcolor nvgRGBAf(float r, float g, float b, float a) { return {}; }
- inline void nvgBeginPath(void* vg) {}
- inline void nvgFillColor(void* vg, NVGcolor) {}
- inline void nvgFillPaint(void* vg, NVGpaint) {}
- inline void nvgFill(void* vg) {}
- inline void nvgStrokeColor(void* vg, NVGcolor) {}
- inline void nvgStrokeWidth(void* vg, float) {}
- inline void nvgStroke(void* vg) {}
- inline void nvgRect(void* vg, float a, float b, float c, float d) {}
- inline void nvgImageSize(void*, int, void*, void*) {}
- inline NVGpaint nvgImagePattern(void*, float, float, float, float, float, int handle, float) { return {}; }
-
- struct json_t {};
- json_t* json_integer(int) { return NULL; }
- json_t* json_object() { return NULL; }
- json_t* json_object_get(json_t*, const char*) { return NULL; }
- int json_integer_value(json_t*) { return 0; }
- void json_object_set_new(json_t*, const char*, json_t*) {}
-
- namespace rack {
-
- struct Quantity {
- virtual ~Quantity() {}
- virtual void setValue(float value) {}
- virtual float getValue() { return 0.f; }
- virtual float getMinValue() { return 0.f; }
- virtual float getMaxValue() { return 1.f; }
- virtual float getDefaultValue() { return 0.f; }
- // virtual float getDisplayValue();
- // virtual void setDisplayValue(float displayValue);
- // virtual int getDisplayPrecision();
- // virtual std::string getDisplayValueString();
- // virtual void setDisplayValueString(std::string s);
- virtual std::string getLabel() { return ""; }
- virtual std::string getUnit() { return ""; }
- // virtual std::string getString();
- // virtual void reset();
- // virtual void randomize();
- // bool isMin();
- // bool isMax();
- // void setMin();
- // void setMax();
- // void toggle();
- // void moveValue(float deltaValue);
- // float getRange();
- // bool isBounded();
- // float toScaled(float value);
- // float fromScaled(float scaledValue);
- // void setScaledValue(float scaledValue);
- // float getScaledValue();
- // void moveScaledValue(float deltaScaledValue);
- };
-
- namespace ui {
- struct Menu;
- }
-
- namespace math {
-
- inline int clamp(int x, int a, int b) {
- return std::max(std::min(x, b), a);
- }
-
- inline float clamp(float x, float a = 0.f, float b = 1.f) {
- return std::fmax(std::fmin(x, b), a);
- }
-
- struct Vec {
- float x = 0.f;
- float y = 0.f;
- Vec() {}
- Vec(float xy) : x(xy), y(xy) {}
- Vec(float x, float y) : x(x), y(y) {}
- Vec neg() const { return Vec(-x, -y); }
- Vec plus(Vec b) const { return Vec(x + b.x, y + b.y); }
- Vec minus(Vec b) const { return Vec(x - b.x, y - b.y); }
- Vec mult(float s) const { return Vec(x * s, y * s); }
- Vec mult(Vec b) const { return Vec(x * b.x, y * b.y); }
- };
-
- struct Rect {
- Vec pos;
- Vec size;
- };
-
- } // namespace math
-
- namespace engine {
-
- static constexpr const int PORT_MAX_CHANNELS = 16;
-
- struct Module;
-
- struct Engine {
- float getSampleRate() { return sampleRate; }
- // custom
- float sampleRate = 0.f;
- };
-
- struct Light {
- float value = 0.f;
- void setBrightness(float brightness) {
- value = brightness;
- }
- float getBrightness() {
- return value;
- }
- void setBrightnessSmooth(float brightness, float deltaTime, float lambda = 30.f) {
- if (brightness < value) {
- // Fade out light
- value += (brightness - value) * lambda * deltaTime;
- }
- else {
- // Immediately illuminate light
- value = brightness;
- }
- }
- void setSmoothBrightness(float brightness, float deltaTime) {
- setBrightnessSmooth(brightness, deltaTime);
- }
- void setBrightnessSmooth(float brightness, int frames = 1) {
- setBrightnessSmooth(brightness, frames / 44100.f);
- }
- };
-
- struct Param {
- float value = 0.f;
- float getValue() { return value; }
- void setValue(float value) { this->value = value; }
- };
-
- struct Port {
- union {
- float voltages[PORT_MAX_CHANNELS] = {};
- float value;
- };
- union {
- uint8_t channels = 0;
- uint8_t active;
- };
- Light plugLights[3];
- enum Type {
- INPUT,
- OUTPUT,
- };
-
- void setVoltage(float voltage, int channel = 0) { voltages[channel] = voltage; }
- float getVoltage(int channel = 0) { return voltages[channel]; }
- float getPolyVoltage(int channel) { return isMonophonic() ? getVoltage(0) : getVoltage(channel); }
-
- float getNormalVoltage(float normalVoltage, int channel = 0) { return isConnected() ? getVoltage(channel) : normalVoltage; }
-
- float getNormalPolyVoltage(float normalVoltage, int channel) { return isConnected() ? getPolyVoltage(channel) : normalVoltage; }
-
- float* getVoltages(int firstChannel = 0) { return &voltages[firstChannel]; }
-
- void readVoltages(float* v) {
- for (int c = 0; c < channels; c++) {
- v[c] = voltages[c];
- }
- }
-
- void writeVoltages(const float* v) {
- for (int c = 0; c < channels; c++) {
- voltages[c] = v[c];
- }
- }
-
- void clearVoltages() {
- for (int c = 0; c < channels; c++) {
- voltages[c] = 0.f;
- }
- }
-
- float getVoltageSum() {
- float sum = 0.f;
- for (int c = 0; c < channels; c++) {
- sum += voltages[c];
- }
- return sum;
- }
-
- float getVoltageRMS() {
- if (channels == 0) {
- return 0.f;
- }
- else if (channels == 1) {
- return std::fabs(voltages[0]);
- }
- else {
- float sum = 0.f;
- for (int c = 0; c < channels; c++) {
- sum += std::pow(voltages[c], 2);
- }
- return std::sqrt(sum);
- }
- }
-
- // template <typename T>
- // T getVoltageSimd(int firstChannel) {
- // return T::load(&voltages[firstChannel]);
- // }
- //
- // template <typename T>
- // T getPolyVoltageSimd(int firstChannel) {
- // return isMonophonic() ? getVoltage(0) : getVoltageSimd<T>(firstChannel);
- // }
- //
- // template <typename T>
- // T getNormalVoltageSimd(T normalVoltage, int firstChannel) {
- // return isConnected() ? getVoltageSimd<T>(firstChannel) : normalVoltage;
- // }
- //
- // template <typename T>
- // T getNormalPolyVoltageSimd(T normalVoltage, int firstChannel) {
- // return isConnected() ? getPolyVoltageSimd<T>(firstChannel) : normalVoltage;
- // }
- //
- // template <typename T>
- // void setVoltageSimd(T voltage, int firstChannel) {
- // voltage.store(&voltages[firstChannel]);
- // }
-
- void setChannels(int channels) {
- if (this->channels == 0) {
- return;
- }
- for (int c = channels; c < this->channels; c++) {
- voltages[c] = 0.f;
- }
- if (channels == 0) {
- channels = 1;
- }
- this->channels = channels;
- }
-
- int getChannels() { return channels; }
- bool isConnected() { return channels > 0; }
- bool isMonophonic() { return channels == 1; }
- bool isPolyphonic() { return channels > 1; }
- float normalize(float normalVoltage) { return getNormalVoltage(normalVoltage); }
- };
-
- struct Output : Port {};
-
- struct Input : Port {};
-
- struct PortInfo {
- Module* module = NULL;
- Port::Type type = Port::INPUT;
- int portId = -1;
- std::string name;
- std::string description;
- virtual ~PortInfo() {}
- virtual std::string getName() {
- if (name == "")
- return std::string("#") + std::to_string(portId + 1);
- return name;
- }
- std::string getFullName() {
- std::string name = getName();
- name += " ";
- name += (type == Port::INPUT) ? "input" : "output";
- return name;
- }
- virtual std::string getDescription() { return description; }
- };
-
- struct ParamQuantity : Quantity {
- Module* module = NULL;
- int paramId = -1;
- float minValue = 0.f;
- float maxValue = 1.f;
- float defaultValue = 0.f;
- std::string name;
- std::string unit;
- float displayBase = 0.f;
- float displayMultiplier = 1.f;
- float displayOffset = 0.f;
- int displayPrecision = 5;
- std::string description;
- bool resetEnabled = true;
- bool randomizeEnabled = true;
- bool smoothEnabled = false;
- bool snapEnabled = false;
-
- // Param* getParam();
- // /** If smoothEnabled is true, requests to the engine to smoothly move to a target value each sample. */
- // void setSmoothValue(float value);
- // float getSmoothValue();
-
- // void setValue(float value) override;
- // float getValue() override;
- float getMinValue() override { return minValue; }
- float getMaxValue() override { return maxValue; }
- float getDefaultValue() override { return defaultValue; }
- // float getDisplayValue() override;
- // void setDisplayValue(float displayValue) override;
- // std::string getDisplayValueString() override;
- // void setDisplayValueString(std::string s) override;
- // int getDisplayPrecision() override;
- // std::string getLabel() override;
- // std::string getUnit() override;
- // void reset() override;
- // void randomize() override;
-
- virtual std::string getDescription() { return description; }
-
- // virtual json_t* toJson();
- // virtual void fromJson(json_t* rootJ);
- };
-
- struct SwitchQuantity : ParamQuantity {
- // std::vector<std::string> labels;
- // std::string getDisplayValueString() override;
- // void setDisplayValueString(std::string s) override;
- };
-
- struct Module {
- std::vector<Param> params;
- std::vector<Input> inputs;
- std::vector<Output> outputs;
- std::vector<Light> lights;
- std::vector<ParamQuantity*> paramQuantities;
- std::vector<PortInfo*> inputInfos;
- std::vector<PortInfo*> outputInfos;
- // std::vector<LightInfo*> lightInfos;
-
- virtual ~Module() {
- for (ParamQuantity* paramQuantity : paramQuantities) {
- if (paramQuantity)
- delete paramQuantity;
- }
- for (PortInfo* inputInfo : inputInfos) {
- if (inputInfo)
- delete inputInfo;
- }
- for (PortInfo* outputInfo : outputInfos) {
- if (outputInfo)
- delete outputInfo;
- }
- // for (LightInfo* lightInfo : lightInfos) {
- // if (lightInfo)
- // delete lightInfo;
- // }
- }
-
- void config(int numParams, int numInputs, int numOutputs, int numLights = 0) {
- // // This method should only be called once.
- // assert(params.empty() && inputs.empty() && outputs.empty() && lights.empty() && paramQuantities.empty());
- params.resize(numParams);
- inputs.resize(numInputs);
- outputs.resize(numOutputs);
- lights.resize(numLights);
- paramQuantities.resize(numParams);
- for (int i = 0; i < numParams; i++) {
- configParam(i, 0.f, 1.f, 0.f);
- }
- inputInfos.resize(numInputs);
- for (int i = 0; i < numInputs; i++) {
- configInput(i);
- }
- outputInfos.resize(numOutputs);
- for (int i = 0; i < numOutputs; i++) {
- configOutput(i);
- }
- // lightInfos.resize(numLights);
- }
-
- template <class TParamQuantity = ParamQuantity>
- TParamQuantity* 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) {
- // assert(paramId < (int) params.size() && paramId < (int) paramQuantities.size());
- if (paramQuantities[paramId])
- delete paramQuantities[paramId];
-
- TParamQuantity* q = new TParamQuantity;
- q->ParamQuantity::module = this;
- q->ParamQuantity::paramId = paramId;
- q->ParamQuantity::minValue = minValue;
- q->ParamQuantity::maxValue = maxValue;
- q->ParamQuantity::defaultValue = defaultValue;
- q->ParamQuantity::name = name;
- q->ParamQuantity::unit = unit;
- q->ParamQuantity::displayBase = displayBase;
- q->ParamQuantity::displayMultiplier = displayMultiplier;
- q->ParamQuantity::displayOffset = displayOffset;
- paramQuantities[paramId] = q;
-
- Param* p = ¶ms[paramId];
- p->value = q->getDefaultValue();
- return q;
- }
-
- template <class TSwitchQuantity = SwitchQuantity>
- TSwitchQuantity* configSwitch(int paramId, float minValue, float maxValue, float defaultValue, std::string name = "", std::vector<std::string> labels = {}) {
- TSwitchQuantity* sq = configParam<TSwitchQuantity>(paramId, minValue, maxValue, defaultValue, name);
- sq->labels = labels;
- return sq;
- }
-
- template <class TSwitchQuantity = SwitchQuantity>
- TSwitchQuantity* configButton(int paramId, std::string name = "") {
- TSwitchQuantity* sq = configParam<TSwitchQuantity>(paramId, 0.f, 1.f, 0.f, name);
- sq->randomizeEnabled = false;
- return sq;
- }
-
- template <class TPortInfo = PortInfo>
- TPortInfo* configInput(int portId, std::string name = "") {
- // assert(portId < (int) inputs.size() && portId < (int) inputInfos.size());
- if (inputInfos[portId])
- delete inputInfos[portId];
-
- TPortInfo* info = new TPortInfo;
- info->PortInfo::module = this;
- info->PortInfo::type = Port::INPUT;
- info->PortInfo::portId = portId;
- info->PortInfo::name = name;
- inputInfos[portId] = info;
- return info;
- }
-
- template <class TPortInfo = PortInfo>
- TPortInfo* configOutput(int portId, std::string name = "") {
- // assert(portId < (int) outputs.size() && portId < (int) outputInfos.size());
- if (outputInfos[portId])
- delete outputInfos[portId];
-
- TPortInfo* info = new TPortInfo;
- info->PortInfo::module = this;
- info->PortInfo::type = Port::OUTPUT;
- info->PortInfo::portId = portId;
- info->PortInfo::name = name;
- outputInfos[portId] = info;
- return info;
- }
-
- // template <class TLightInfo = LightInfo>
- // TLightInfo* configLight(int lightId, std::string name = "") {
- // assert(lightId < (int) lights.size() && lightId < (int) lightInfos.size());
- // if (lightInfos[lightId])
- // delete lightInfos[lightId];
- //
- // TLightInfo* info = new TLightInfo;
- // info->LightInfo::module = this;
- // info->LightInfo::lightId = lightId;
- // info->LightInfo::name = name;
- // lightInfos[lightId] = info;
- // return info;
- // }
-
- void configBypass(int inputId, int outputId) {
- // assert(inputId < (int) inputs.size());
- // assert(outputId < (int) outputs.size());
- // // Check that output is not yet routed
- // for (BypassRoute& br : bypassRoutes) {
- // assert(br.outputId != outputId);
- // }
- //
- // BypassRoute br;
- // br.inputId = inputId;
- // br.outputId = outputId;
- // bypassRoutes.push_back(br);
- }
-
- int getNumParams() { return params.size(); }
- Param& getParam(int index) { return params[index]; }
- int getNumInputs() { return inputs.size(); }
- Input& getInput(int index) { return inputs[index]; }
- int getNumOutputs() { return outputs.size(); }
- Output& getOutput(int index) { return outputs[index]; }
- int getNumLights() { return lights.size(); }
- Light& getLight(int index) { return lights[index]; }
- ParamQuantity* getParamQuantity(int index) { return paramQuantities[index]; }
- PortInfo* getInputInfo(int index) { return inputInfos[index]; }
- PortInfo* getOutputInfo(int index) { return outputInfos[index]; }
- // LightInfo* getLightInfo(int index) { return lightInfos[index]; }
-
- struct ProcessArgs {
- float sampleRate;
- float sampleTime;
- int64_t frame;
- };
- virtual void process(const ProcessArgs& args) {
- step();
- }
- virtual void step() {}
-
- // virtual void processBypass(const ProcessArgs& args);
-
- // virtual json_t* toJson();
- // virtual void fromJson(json_t* rootJ);
-
- /** Serializes the "params" object. */
- // virtual json_t* paramsToJson();
- // virtual void paramsFromJson(json_t* rootJ);
-
- virtual json_t* dataToJson() { return NULL; }
- virtual void dataFromJson(json_t* rootJ) {}
-
- struct SampleRateChangeEvent {
- float sampleRate;
- float sampleTime;
- };
- virtual void onSampleRateChange(const SampleRateChangeEvent& e) {
- onSampleRateChange();
- }
-
- struct ResetEvent {};
- virtual void onReset(const ResetEvent& e) {} // TODO
-
- virtual void onAdd() {}
- virtual void onRemove() {}
- virtual void onReset() {}
- virtual void onRandomize() {}
- virtual void onSampleRateChange() {}
-
- // private
- void doProcess(const ProcessArgs& args) {
- // if (!internal->bypassed)
- process(args);
- // else
- // processBypass(args);
-
- // if (args.frame % PORT_DIVIDER == 0) {
- // float portTime = args.sampleTime * PORT_DIVIDER;
- // for (Input& input : inputs) {
- // Port_step(&input, portTime);
- // }
- // for (Output& output : outputs) {
- // Port_step(&output, portTime);
- // }
- // }
- }
- };
-
- } // namespace engine
-
- namespace widget {
-
- struct BaseEvent {
- };
-
- struct Widget {
- math::Rect box;
- Widget* parent = NULL;
- std::list<Widget*> children;
- bool visible = true;
- bool requestedDelete = false;
-
- using BaseEvent = widget::BaseEvent;
-
- struct ActionEvent : BaseEvent {};
- virtual void onAction(const ActionEvent& e) {}
-
- struct ChangeEvent : BaseEvent {};
- virtual void onChange(const ChangeEvent& e) {}
-
- bool hasChild(Widget* child) { return false; }
- void addChild(Widget* child) {}
- void addChildBottom(Widget* child) {}
- void addChildBelow(Widget* child, Widget* sibling) {}
- void addChildAbove(Widget* child, Widget* sibling) {}
- void removeChild(Widget* child) {}
- void clearChildren() {}
- virtual void step() {}
- struct DrawArgs {
- void* vg = NULL;
- math::Rect clipBox;
- void* fb = NULL;
- };
- virtual void draw(const DrawArgs& args);
- };
-
- struct OpaqueWidget : Widget {
- };
-
- struct SvgWidget : Widget {
- void wrap() {}
- void setSvg(void* svg) {}
- };
-
- struct TransparentWidget : Widget {
- };
-
- } // namespace widget
-
- namespace app {
-
- static constexpr const float RACK_GRID_WIDTH = 15;
- static constexpr const float RACK_GRID_HEIGHT = 380;
- // static constexpr const math::Vec RACK_GRID_SIZE = math::Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
- // static constexpr const math::Vec RACK_OFFSET = RACK_GRID_SIZE.mult(math::Vec(2000, 100));
-
- struct CircularShadow : widget::TransparentWidget {
- float blurRadius;
- float opacity;
- };
-
- struct LightWidget : widget::TransparentWidget {
- NVGcolor bgColor, color, borderColor;
- };
-
- struct ModuleWidget : widget::OpaqueWidget {
- // plugin::Model* model = NULL;
- engine::Module* module = NULL;
- void setModel(void*) {}
- void setModule(void*) {}
- void setPanel(void*) {}
- void addParam(void*) {}
- void addInput(void*) {}
- void addOutput(void*) {}
- virtual void appendContextMenu(ui::Menu* menu) {}
- };
-
- struct MultiLightWidget : LightWidget {
- // std::vector<NVGcolor> baseColors;
- // int getNumColors();
- void addBaseColor(NVGcolor baseColor) {}
- // void setBrightnesses(const std::vector<float>& brightnesses);
- };
-
- struct ModuleLightWidget : MultiLightWidget {
- // engine::Module* module = NULL;
- // int firstLightId = -1;
- // ModuleLightWidget();
- // ~ModuleLightWidget();
- // engine::Light* getLight(int colorId);
- // engine::LightInfo* getLightInfo();
- // void createTooltip();
- // void destroyTooltip();
- };
-
- struct ParamWidget : widget::OpaqueWidget {
- engine::Module* module = NULL;
- int paramId = -1;
- virtual void initParamQuantity() {}
- engine::ParamQuantity* getParamQuantity() { return module ? module->paramQuantities[paramId] : NULL; }
- void createTooltip() {}
- void destroyTooltip() {}
- void createContextMenu();
- virtual void appendContextMenu(void* menu) {}
- void resetAction();
- };
-
- struct PortWidget : widget::OpaqueWidget {
- };
-
- struct Knob : ParamWidget {
- bool horizontal = false;
- bool smooth = true;
- bool snap = false;
- float speed = 1.f;
- bool forceLinear = false;
- float minAngle = -M_PI;
- float maxAngle = M_PI;
- };
-
- struct SliderKnob : Knob {
- };
-
- struct Switch : ParamWidget {
- bool momentary = false;
- };
-
- struct SvgKnob : Knob {
- CircularShadow* shadow;
- void setSvg(void* svg) {}
- };
-
- struct SvgPanel : widget::Widget {
- // widget::FramebufferWidget* fb;
- // widget::SvgWidget* sw;
- // PanelBorder* panelBorder;
- void setBackground(void* svg) {}
- };
-
- struct SvgPort : PortWidget {
- // widget::FramebufferWidget* fb;
- CircularShadow* shadow;
- // widget::SvgWidget* sw;
- void setSvg(void* svg) {}
- };
-
- struct SvgScrew : widget::Widget {
- // widget::FramebufferWidget* fb;
- widget::SvgWidget* sw;
- void setSvg(void* svg) {}
- };
-
- struct SvgSlider : app::SliderKnob {
- // widget::FramebufferWidget* fb;
- widget::SvgWidget* background;
- // widget::SvgWidget* handle;
- math::Vec minHandlePos, maxHandlePos;
- void setBackgroundSvg(void* svg) {}
- void setHandleSvg(void* svg) {}
- void setHandlePos(math::Vec minHandlePos, math::Vec maxHandlePos) {}
- void setHandlePosCentered(math::Vec minHandlePosCentered, math::Vec maxHandlePosCentered) {}
- };
-
- struct SvgSwitch : Switch {
- // widget::FramebufferWidget* fb;
- // CircularShadow* shadow;
- // widget::SvgWidget* sw;
- // std::vector<std::shared_ptr<window::Svg>> frames;
- bool latch = false;
- void addFrame(void* svg) {}
- };
-
- } // namespace app
-
- namespace asset {
-
- const char* plugin(void* instance, const char* path) {
- return NULL;
- }
-
- } // namespace asset
-
- namespace componentlibrary {
-
- static constexpr const NVGcolor SCHEME_LIGHT_GRAY = {};
-
- template <typename TBase = app::ModuleLightWidget>
- struct TSvgLight : TBase {
- // widget::FramebufferWidget* fb;
- // widget::SvgWidget* sw;
- void setSvg(void* svg) {}
- };
- using SvgLight = TSvgLight<>;
-
- template <typename TBase = app::ModuleLightWidget>
- struct TGrayModuleLightWidget : TBase {
- };
- using GrayModuleLightWidget = TGrayModuleLightWidget<>;
-
- template <typename TBase = GrayModuleLightWidget>
- struct TWhiteLight : TBase {
- };
- using WhiteLight = TWhiteLight<>;
-
- template <typename TBase = GrayModuleLightWidget>
- struct TRedLight : TBase {
- };
- using RedLight = TRedLight<>;
-
- template <typename TBase = GrayModuleLightWidget>
- struct TGreenLight : TBase {
- };
- using GreenLight = TGreenLight<>;
-
- template <typename TBase = GrayModuleLightWidget>
- struct TBlueLight : TBase {
- };
- using BlueLight = TBlueLight<>;
-
- template <typename TBase = GrayModuleLightWidget>
- struct TYellowLight : TBase {
- };
- using YellowLight = TYellowLight<>;
-
- template <typename TBase = GrayModuleLightWidget>
- struct TGreenRedLight : TBase {
- };
- using GreenRedLight = TGreenRedLight<>;
-
- template <typename TBase = GrayModuleLightWidget>
- struct TRedGreenBlueLight : TBase {
- };
- using RedGreenBlueLight = TRedGreenBlueLight<>;
-
- template <typename TBase>
- struct LargeLight : TSvgLight<TBase> {
- };
-
- template <typename TBase>
- struct MediumLight : TSvgLight<TBase> {
- };
-
- template <typename TBase>
- struct SmallLight : TSvgLight<TBase> {
- };
-
- template <typename TBase>
- struct TinyLight : TSvgLight<TBase> {
- };
-
- struct ScrewBlack : app::SvgScrew {
- };
-
- } // namespace componentlibrary
-
- namespace dsp {
-
- inline float sinc(float x) {
- if (x == 0.f)
- return 1.f;
- x *= M_PI;
- return std::sin(x) / x;
- }
-
- // template <typename T>
- // T sinc(T x) {
- // T zeromask = (x == 0.f);
- // x *= M_PI;
- // x = simd::sin(x) / x;
- // return simd::ifelse(zeromask, 1.f, x);
- // }
-
- template <typename T>
- inline T blackmanHarris(T p) {
- return
- + T(0.35875)
- - T(0.48829) * std::cos(2 * T(M_PI) * p)
- + T(0.14128) * std::cos(4 * T(M_PI) * p)
- - T(0.01168) * std::cos(6 * T(M_PI) * p);
- }
-
- inline void blackmanHarrisWindow(float* x, int len) {
- for (int i = 0; i < len; i++) {
- x[i] *= blackmanHarris(float(i) / (len - 1));
- }
- }
-
- inline void boxcarLowpassIR(float* out, int len, float cutoff = 0.5f) {
- for (int i = 0; i < len; i++) {
- float t = i - (len - 1) / 2.f;
- out[i] = 2 * cutoff * sinc(2 * cutoff * t);
- }
- }
-
- template <int OVERSAMPLE, int QUALITY, typename T = float>
- struct Decimator {
- T inBuffer[OVERSAMPLE * QUALITY];
- float kernel[OVERSAMPLE * QUALITY];
- int inIndex;
- Decimator(float cutoff = 0.9f) {
- boxcarLowpassIR(kernel, OVERSAMPLE * QUALITY, cutoff * 0.5f / OVERSAMPLE);
- blackmanHarrisWindow(kernel, OVERSAMPLE * QUALITY);
- reset();
- }
- void reset() {
- inIndex = 0;
- std::memset(inBuffer, 0, sizeof(inBuffer));
- }
- T process(T* in) {
- std::memcpy(&inBuffer[inIndex], in, OVERSAMPLE * sizeof(T));
- inIndex += OVERSAMPLE;
- inIndex %= OVERSAMPLE * QUALITY;
- T out = 0.f;
- for (int i = 0; i < OVERSAMPLE * QUALITY; i++) {
- int index = inIndex - 1 - i;
- index = (index + OVERSAMPLE * QUALITY) % (OVERSAMPLE * QUALITY);
- out += kernel[i] * inBuffer[index];
- }
- return out;
- }
- };
-
- struct PulseGenerator {
- float remaining = 0.f;
- void reset() { remaining = 0.f; }
- bool process(float deltaTime) {
- if (remaining > 0.f) {
- remaining -= deltaTime;
- return true;
- }
- return false;
- }
- void trigger(float duration = 1e-3f) {
- if (duration > remaining) {
- remaining = duration;
- }
- }
- };
-
- } // namespace dsp
-
- namespace event {
- // using Base = widget::BaseEvent;
- // using PositionBase = widget::Widget::PositionBaseEvent;
- // using KeyBase = widget::Widget::KeyBaseEvent;
- // using TextBase = widget::Widget::TextBaseEvent;
- // using Hover = widget::Widget::HoverEvent;
- // using Button = widget::Widget::ButtonEvent;
- // using DoubleClick = widget::Widget::DoubleClickEvent;
- // using HoverKey = widget::Widget::HoverKeyEvent;
- // using HoverText = widget::Widget::HoverTextEvent;
- // using HoverScroll = widget::Widget::HoverScrollEvent;
- // using Enter = widget::Widget::EnterEvent;
- // using Leave = widget::Widget::LeaveEvent;
- // using Select = widget::Widget::SelectEvent;
- // using Deselect = widget::Widget::DeselectEvent;
- // using SelectKey = widget::Widget::SelectKeyEvent;
- // using SelectText = widget::Widget::SelectTextEvent;
- // using DragBase = widget::Widget::DragBaseEvent;
- // using DragStart = widget::Widget::DragStartEvent;
- // using DragEnd = widget::Widget::DragEndEvent;
- // using DragMove = widget::Widget::DragMoveEvent;
- // using DragHover = widget::Widget::DragHoverEvent;
- // using DragEnter = widget::Widget::DragEnterEvent;
- // using DragLeave = widget::Widget::DragLeaveEvent;
- // using DragDrop = widget::Widget::DragDropEvent;
- // using PathDrop = widget::Widget::PathDropEvent;
- using Action = widget::Widget::ActionEvent;
- using Change = widget::Widget::ChangeEvent;
- // using Dirty = widget::Widget::DirtyEvent;
- // using Reposition = widget::Widget::RepositionEvent;
- // using Resize = widget::Widget::ResizeEvent;
- // using Add = widget::Widget::AddEvent;
- // using Remove = widget::Widget::RemoveEvent;
- // using Show = widget::Widget::ShowEvent;
- // using Hide = widget::Widget::HideEvent;
- } // namespace event
-
- namespace plugin {
-
- struct Model {
- virtual ~Model() {}
- virtual engine::Module* createModule() = 0;
- };
-
- struct Plugin {
- };
-
- } // namespace plugin
-
- namespace ui {
-
- struct Menu : widget::OpaqueWidget {
- // Menu* parentMenu = NULL;
- // Menu* childMenu = NULL;
- // MenuEntry* activeEntry = NULL;
- // BNDcornerFlags cornerFlags = BND_CORNER_NONE;
- // void setChildMenu(Menu* menu) {}
- };
-
- struct MenuEntry : widget::OpaqueWidget {
- };
-
- struct MenuItem : MenuEntry {
- std::string text;
- std::string rightText;
- bool disabled = false;
- };
-
- struct MenuLabel : MenuEntry {
- std::string text;
- };
-
- } // namespace ui
-
- namespace window {
-
- static constexpr const float SVG_DPI = 75.f;
- static constexpr const float MM_PER_IN = 25.4f;
-
- inline float in2px(float in) { return in * SVG_DPI; }
- inline math::Vec in2px(math::Vec in) { return in.mult(SVG_DPI); }
- inline float mm2px(float mm) { return mm * (SVG_DPI / MM_PER_IN); }
- inline math::Vec mm2px(math::Vec mm) { return mm.mult(SVG_DPI / MM_PER_IN); }
-
- struct Image {
- int handle;
- };
-
- struct Window {
- std::shared_ptr<Image> loadImage(const std::string&) { return {}; }
- void* loadSvg(const void*) { return NULL; }
- };
-
- };
-
- using namespace app;
- using namespace componentlibrary;
- using namespace engine;
- using namespace math;
- using namespace ui;
- using namespace widget;
- using namespace window;
- using plugin::Plugin;
- using plugin::Model;
-
- template <class TModule, class TModuleWidget>
- plugin::Model* createModel(std::string slug) {
- struct TModel : plugin::Model {
- engine::Module* createModule() override {
- return new TModule;
- }
- };
- return new TModel;
- }
-
- template <typename T>
- T* construct() { return NULL; }
-
- template <typename T, typename F, typename V, typename... Args>
- T* construct(F f, V v, Args... args) { return NULL; }
-
- template <class TWidget>
- TWidget* createWidget(math::Vec pos) {
- return NULL;
- }
-
- template <class TParamWidget>
- TParamWidget* createParam(math::Vec pos, engine::Module* module, int paramId) {
- return NULL;
- }
-
- template <class TParamWidget>
- TParamWidget* createParamCentered(math::Vec pos, engine::Module* module, int paramId) {
- return NULL;
- }
-
- template <class TPortWidget>
- TPortWidget* createInput(math::Vec pos, engine::Module* module, int inputId) {
- return NULL;
- }
-
- template <class TPortWidget>
- TPortWidget* createInputCentered(math::Vec pos, engine::Module* module, int inputId) {
- return NULL;
- }
-
- template <class TPortWidget>
- TPortWidget* createOutput(math::Vec pos, engine::Module* module, int outputId) {
- return NULL;
- }
-
- template <class TPortWidget>
- TPortWidget* createOutputCentered(math::Vec pos, engine::Module* module, int outputId) {
- return NULL;
- }
-
- template <class TModuleLightWidget>
- TModuleLightWidget* createLight(math::Vec pos, engine::Module* module, int firstLightId) {
- return NULL;
- }
-
- template <class TModuleLightWidget>
- TModuleLightWidget* createLightCentered(math::Vec pos, engine::Module* module, int firstLightId) {
- return NULL;
- }
-
- struct Context {
- engine::Engine _engine;
- window::Window _window;
- engine::Engine* engine = &_engine;
- window::Window* window = &_window;
- };
-
- Context* contextGet();
- void contextSet(Context* context);
-
- } // namespace rack
-
- #define APP rack::contextGet()
|