@@ -2,7 +2,6 @@ | |||||
#include "ui/Quantity.hpp" | #include "ui/Quantity.hpp" | ||||
#include "engine/Module.hpp" | #include "engine/Module.hpp" | ||||
#include "engine/Param.hpp" | #include "engine/Param.hpp" | ||||
#include "engine/ParamInfo.hpp" | |||||
namespace rack { | namespace rack { | ||||
@@ -14,7 +13,6 @@ struct ParamQuantity : Quantity { | |||||
int paramId = 0; | int paramId = 0; | ||||
Param *getParam(); | Param *getParam(); | ||||
ParamInfo *getParamInfo(); | |||||
/** Request to the engine to smoothly set the value */ | /** Request to the engine to smoothly set the value */ | ||||
void setSmoothValue(float smoothValue); | void setSmoothValue(float smoothValue); | ||||
float getSmoothValue(); | float getSmoothValue(); | ||||
@@ -5,7 +5,6 @@ | |||||
#include "engine/Input.hpp" | #include "engine/Input.hpp" | ||||
#include "engine/Output.hpp" | #include "engine/Output.hpp" | ||||
#include "engine/Light.hpp" | #include "engine/Light.hpp" | ||||
#include "engine/ParamInfo.hpp" | |||||
#include <vector> | #include <vector> | ||||
#include <jansson.h> | #include <jansson.h> | ||||
@@ -19,7 +18,6 @@ struct Module { | |||||
std::vector<Input> inputs; | std::vector<Input> inputs; | ||||
std::vector<Output> outputs; | std::vector<Output> outputs; | ||||
std::vector<Light> lights; | std::vector<Light> lights; | ||||
std::vector<ParamInfo> paramInfos; | |||||
/** For power meter */ | /** For power meter */ | ||||
float cpuTime = 0.f; | float cpuTime = 0.f; | ||||
bool bypass = false; | bool bypass = false; | ||||
@@ -6,19 +6,55 @@ | |||||
namespace rack { | namespace rack { | ||||
struct ParamQuantity; | |||||
struct ParamQuantityFactory { | |||||
virtual ~ParamQuantityFactory() {} | |||||
virtual ParamQuantity *create() = 0; | |||||
}; | |||||
struct Param { | struct Param { | ||||
float value = 0.f; | float value = 0.f; | ||||
float minValue = 0.f; | float minValue = 0.f; | ||||
float maxValue = 1.f; | float maxValue = 1.f; | ||||
float defaultValue = 0.f; | float defaultValue = 0.f; | ||||
void config(float minValue, float maxValue, float defaultValue) { | |||||
std::string label; | |||||
std::string unit; | |||||
/** Set to 0 for linear, nonzero for exponential */ | |||||
float displayBase = 0.f; | |||||
float displayMultiplier = 1.f; | |||||
std::string description; | |||||
ParamQuantityFactory *paramQuantityFactory = NULL; | |||||
~Param() { | |||||
if (paramQuantityFactory) | |||||
delete paramQuantityFactory; | |||||
} | |||||
template<class TParamQuantity = ParamQuantity> | |||||
void config(float minValue, float maxValue, float defaultValue, std::string label = "", std::string unit = "", float displayBase = 0.f, float displayMultiplier = 1.f) { | |||||
this->value = defaultValue; | this->value = defaultValue; | ||||
this->minValue = minValue; | this->minValue = minValue; | ||||
this->maxValue = maxValue; | this->maxValue = maxValue; | ||||
this->defaultValue = defaultValue; | this->defaultValue = defaultValue; | ||||
this->label = label; | |||||
this->unit = unit; | |||||
this->displayBase = displayBase; | |||||
this->displayMultiplier = displayMultiplier; | |||||
struct TParamQuantityFactory : ParamQuantityFactory { | |||||
ParamQuantity *create() override {return new TParamQuantity;} | |||||
}; | |||||
if (paramQuantityFactory) | |||||
delete paramQuantityFactory; | |||||
paramQuantityFactory = new TParamQuantityFactory; | |||||
} | } | ||||
bool isBounded(); | |||||
json_t *toJson(); | json_t *toJson(); | ||||
void fromJson(json_t *rootJ); | void fromJson(json_t *rootJ); | ||||
void reset(); | void reset(); | ||||
@@ -1,48 +0,0 @@ | |||||
#pragma once | |||||
#include "common.hpp" | |||||
namespace rack { | |||||
struct ParamQuantity; | |||||
struct ParamQuantityFactory { | |||||
virtual ~ParamQuantityFactory() {} | |||||
virtual ParamQuantity *create() = 0; | |||||
}; | |||||
struct ParamInfo { | |||||
std::string label; | |||||
std::string unit; | |||||
/** Set to 0 for linear, nonzero for exponential */ | |||||
float displayBase = 0.f; | |||||
float displayMultiplier = 1.f; | |||||
std::string description; | |||||
ParamQuantityFactory *paramQuantityFactory = NULL; | |||||
~ParamInfo() { | |||||
if (paramQuantityFactory) | |||||
delete paramQuantityFactory; | |||||
} | |||||
template<class TParamQuantity = ParamQuantity> | |||||
void config(std::string label = "", std::string unit = "", float displayBase = 0.f, float displayMultiplier = 1.f) { | |||||
this->label = label; | |||||
this->unit = unit; | |||||
this->displayBase = displayBase; | |||||
this->displayMultiplier = displayMultiplier; | |||||
struct TParamQuantityFactory : ParamQuantityFactory { | |||||
ParamQuantity *create() override {return new TParamQuantity;} | |||||
}; | |||||
if (paramQuantityFactory) | |||||
delete paramQuantityFactory; | |||||
paramQuantityFactory = new TParamQuantityFactory; | |||||
} | |||||
}; | |||||
} // namespace rack |
@@ -58,7 +58,7 @@ TParamWidget *createParam(math::Vec pos, Module *module, int paramId) { | |||||
TParamWidget *o = new TParamWidget; | TParamWidget *o = new TParamWidget; | ||||
o->box.pos = pos; | o->box.pos = pos; | ||||
if (module) { | if (module) { | ||||
ParamQuantityFactory *f = module->paramInfos[paramId].paramQuantityFactory; | |||||
ParamQuantityFactory *f = module->params[paramId].paramQuantityFactory; | |||||
if (f) | if (f) | ||||
o->paramQuantity = f->create(); | o->paramQuantity = f->create(); | ||||
else | else | ||||
@@ -11,11 +11,6 @@ Param *ParamQuantity::getParam() { | |||||
return &module->params[paramId]; | return &module->params[paramId]; | ||||
} | } | ||||
ParamInfo *ParamQuantity::getParamInfo() { | |||||
assert(module); | |||||
return &module->paramInfos[paramId]; | |||||
} | |||||
void ParamQuantity::setSmoothValue(float smoothValue) { | void ParamQuantity::setSmoothValue(float smoothValue) { | ||||
if (!module) | if (!module) | ||||
return; | return; | ||||
@@ -63,34 +58,34 @@ float ParamQuantity::getDefaultValue() { | |||||
float ParamQuantity::getDisplayValue() { | float ParamQuantity::getDisplayValue() { | ||||
if (!module) | if (!module) | ||||
return Quantity::getDisplayValue(); | return Quantity::getDisplayValue(); | ||||
if (getParamInfo()->displayBase == 0.f) { | |||||
if (getParam()->displayBase == 0.f) { | |||||
// Linear | // Linear | ||||
return getValue() * getParamInfo()->displayMultiplier; | |||||
return getValue() * getParam()->displayMultiplier; | |||||
} | } | ||||
else if (getParamInfo()->displayBase == 1.f) { | |||||
else if (getParam()->displayBase == 1.f) { | |||||
// Fixed (special case of exponential) | // Fixed (special case of exponential) | ||||
return getParamInfo()->displayMultiplier; | |||||
return getParam()->displayMultiplier; | |||||
} | } | ||||
else { | else { | ||||
// Exponential | // Exponential | ||||
return std::pow(getParamInfo()->displayBase, getValue()) * getParamInfo()->displayMultiplier; | |||||
return std::pow(getParam()->displayBase, getValue()) * getParam()->displayMultiplier; | |||||
} | } | ||||
} | } | ||||
void ParamQuantity::setDisplayValue(float displayValue) { | void ParamQuantity::setDisplayValue(float displayValue) { | ||||
if (!module) | if (!module) | ||||
return; | return; | ||||
if (getParamInfo()->displayBase == 0.f) { | |||||
if (getParam()->displayBase == 0.f) { | |||||
// Linear | // Linear | ||||
setValue(displayValue / getParamInfo()->displayMultiplier); | |||||
setValue(displayValue / getParam()->displayMultiplier); | |||||
} | } | ||||
else if (getParamInfo()->displayBase == 1.f) { | |||||
else if (getParam()->displayBase == 1.f) { | |||||
// Fixed | // Fixed | ||||
setValue(getParamInfo()->displayMultiplier); | |||||
setValue(getParam()->displayMultiplier); | |||||
} | } | ||||
else { | else { | ||||
// Exponential | // Exponential | ||||
setValue(std::log(displayValue / getParamInfo()->displayMultiplier) / std::log(getParamInfo()->displayBase)); | |||||
setValue(std::log(displayValue / getParam()->displayMultiplier) / std::log(getParam()->displayBase)); | |||||
} | } | ||||
} | } | ||||
@@ -109,13 +104,13 @@ int ParamQuantity::getDisplayPrecision() { | |||||
std::string ParamQuantity::getLabel() { | std::string ParamQuantity::getLabel() { | ||||
if (!module) | if (!module) | ||||
return Quantity::getLabel(); | return Quantity::getLabel(); | ||||
return getParamInfo()->label; | |||||
return getParam()->label; | |||||
} | } | ||||
std::string ParamQuantity::getUnit() { | std::string ParamQuantity::getUnit() { | ||||
if (!module) | if (!module) | ||||
return Quantity::getUnit(); | return Quantity::getUnit(); | ||||
return getParamInfo()->unit; | |||||
return getParam()->unit; | |||||
} | } | ||||
@@ -82,7 +82,7 @@ void ParamWidget::step() { | |||||
// Quantity string | // Quantity string | ||||
tooltip->text = paramQuantity->getString(); | tooltip->text = paramQuantity->getString(); | ||||
// Param description | // Param description | ||||
std::string description = paramQuantity->getParamInfo()->description; | |||||
std::string description = paramQuantity->getParam()->description; | |||||
if (!description.empty()) | if (!description.empty()) | ||||
tooltip->text += "\n" + description; | tooltip->text += "\n" + description; | ||||
} | } | ||||
@@ -9,14 +9,13 @@ Module::Module() { | |||||
void Module::config(int numParams, int numInputs, int numOutputs, int numLights) { | void Module::config(int numParams, int numInputs, int numOutputs, int numLights) { | ||||
params.resize(numParams); | params.resize(numParams); | ||||
inputs.resize(numInputs); | |||||
outputs.resize(numOutputs); | |||||
lights.resize(numLights); | |||||
paramInfos.resize(numParams); | |||||
// Create default param labels | // Create default param labels | ||||
for (int i = 0; i < numParams; i++) { | for (int i = 0; i < numParams; i++) { | ||||
paramInfos[i].label = string::f("#%d", i + 1); | |||||
params[i].label = string::f("#%d", i + 1); | |||||
} | } | ||||
inputs.resize(numInputs); | |||||
outputs.resize(numOutputs); | |||||
lights.resize(numLights); | |||||
} | } | ||||
json_t *Module::toJson() { | json_t *Module::toJson() { | ||||
@@ -6,32 +6,37 @@ | |||||
namespace rack { | namespace rack { | ||||
bool Param::isBounded() { | |||||
return std::isfinite(minValue) && std::isfinite(maxValue); | |||||
} | |||||
json_t *Param::toJson() { | json_t *Param::toJson() { | ||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
float v = 0.f; | |||||
// Infinite params should serialize to 0 | // Infinite params should serialize to 0 | ||||
if (std::isfinite(minValue) && std::isfinite(maxValue)) | |||||
v = value; | |||||
json_object_set_new(rootJ, "value", json_real(v)); | |||||
if (isBounded()) { | |||||
json_object_set_new(rootJ, "value", json_real(value)); | |||||
} | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void Param::fromJson(json_t *rootJ) { | void Param::fromJson(json_t *rootJ) { | ||||
json_t *valueJ = json_object_get(rootJ, "value"); | |||||
if (valueJ) | |||||
value = json_number_value(valueJ); | |||||
if (isBounded()) { | |||||
json_t *valueJ = json_object_get(rootJ, "value"); | |||||
if (valueJ) | |||||
value = json_number_value(valueJ); | |||||
} | |||||
} | } | ||||
void Param::reset() { | void Param::reset() { | ||||
if (std::isfinite(minValue) && std::isfinite(maxValue)) { | |||||
if (isBounded()) { | |||||
value = defaultValue; | value = defaultValue; | ||||
} | } | ||||
} | } | ||||
void Param::randomize() { | void Param::randomize() { | ||||
if (std::isfinite(minValue) && std::isfinite(maxValue)) { | |||||
if (isBounded()) { | |||||
value = math::rescale(random::uniform(), 0.f, 1.f, minValue, maxValue); | value = math::rescale(random::uniform(), 0.f, 1.f, minValue, maxValue); | ||||
} | } | ||||
} | } | ||||