@@ -14,7 +14,10 @@ namespace engine { | |||||
struct Module; | struct Module; | ||||
/** A Quantity that wraps an engine::Param. */ | |||||
/** A Quantity that wraps an engine::Param. | |||||
If `smoothEnabled` is true, all methods access/modify the target value of the Engine's smoothing algorithm for a Param instead of the value directly. | |||||
*/ | |||||
struct ParamQuantity : Quantity { | struct ParamQuantity : Quantity { | ||||
Module* module = NULL; | Module* module = NULL; | ||||
int paramId = -1; | int paramId = -1; | ||||
@@ -64,11 +67,26 @@ struct ParamQuantity : Quantity { | |||||
bool snapEnabled = false; | bool snapEnabled = false; | ||||
Param* getParam(); | 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(); | |||||
/** Deprecated. Use setValue() instead. */ | |||||
DEPRECATED void setSmoothValue(float value); | |||||
/** Deprecated. Use getValue() instead. */ | |||||
DEPRECATED float getSmoothValue(); | |||||
void setDirectValue(float value); | |||||
float getDirectValue(); | |||||
/** Sets the Param's smoothing target value, or direct value if smoothing is disabled. | |||||
Before Rack 2.3.0, this always set the Param's value directly. | |||||
For this behavior, use `setDirectValue()` instead. | |||||
*/ | |||||
void setValue(float value) override; | void setValue(float value) override; | ||||
/** Gets the Param's smoothing target value, or direct value if smoothing is disabled. | |||||
Before Rack 2.3.0, this always got the Param's value directly. | |||||
For this behavior, use `getDirectValue()` instead. | |||||
*/ | |||||
float getValue() override; | float getValue() override; | ||||
float getMinValue() override; | float getMinValue() override; | ||||
float getMaxValue() override; | float getMaxValue() override; | ||||
@@ -72,7 +72,7 @@ void Knob::onDragStart(const DragStartEvent& e) { | |||||
engine::ParamQuantity* pq = getParamQuantity(); | engine::ParamQuantity* pq = getParamQuantity(); | ||||
if (pq) { | if (pq) { | ||||
internal->oldValue = pq->getSmoothValue(); | |||||
internal->oldValue = pq->getValue(); | |||||
internal->snapDelta = 0.f; | internal->snapDelta = 0.f; | ||||
} | } | ||||
@@ -103,7 +103,7 @@ void Knob::onDragEnd(const DragEndEvent& e) { | |||||
engine::ParamQuantity* pq = getParamQuantity(); | engine::ParamQuantity* pq = getParamQuantity(); | ||||
if (pq) { | if (pq) { | ||||
float newValue = pq->getSmoothValue(); | |||||
float newValue = pq->getValue(); | |||||
if (!std::isnan(internal->oldValue) && internal->oldValue != newValue) { | if (!std::isnan(internal->oldValue) && internal->oldValue != newValue) { | ||||
// Push ParamChange history action | // Push ParamChange history action | ||||
history::ParamChange* h = new history::ParamChange; | history::ParamChange* h = new history::ParamChange; | ||||
@@ -150,7 +150,7 @@ void Knob::onDragMove(const DragMoveEvent& e) { | |||||
engine::ParamQuantity* pq = getParamQuantity(); | engine::ParamQuantity* pq = getParamQuantity(); | ||||
if (pq) { | if (pq) { | ||||
float value = pq->getSmoothValue(); | |||||
float value = pq->getValue(); | |||||
// Ratio between parameter value scale / (angle range / 2*pi) | // Ratio between parameter value scale / (angle range / 2*pi) | ||||
float rangeRatio; | float rangeRatio; | ||||
@@ -224,7 +224,7 @@ void Knob::onDragMove(const DragMoveEvent& e) { | |||||
} | } | ||||
// Set value | // Set value | ||||
pq->setSmoothValue(value); | |||||
pq->setValue(value); | |||||
} | } | ||||
internal->distDragged += e.mouseDelta.norm(); | internal->distDragged += e.mouseDelta.norm(); | ||||
@@ -254,7 +254,7 @@ void Knob::onHoverScroll(const HoverScrollEvent& e) { | |||||
if (!pq) | if (!pq) | ||||
return; | return; | ||||
float value = pq->getSmoothValue(); | |||||
float value = pq->getValue(); | |||||
// Set old value if unset | // Set old value if unset | ||||
if (std::isnan(internal->oldValue)) { | if (std::isnan(internal->oldValue)) { | ||||
internal->oldValue = value; | internal->oldValue = value; | ||||
@@ -284,7 +284,7 @@ void Knob::onHoverScroll(const HoverScrollEvent& e) { | |||||
} | } | ||||
value += delta; | value += delta; | ||||
pq->setSmoothValue(value); | |||||
pq->setValue(value); | |||||
e.consume(this); | e.consume(this); | ||||
} | } | ||||
@@ -298,7 +298,7 @@ void Knob::onLeave(const LeaveEvent& e) { | |||||
engine::ParamQuantity* pq = getParamQuantity(); | engine::ParamQuantity* pq = getParamQuantity(); | ||||
if (pq) { | if (pq) { | ||||
float newValue = pq->getSmoothValue(); | |||||
float newValue = pq->getValue(); | |||||
if (!std::isnan(internal->oldValue) && internal->oldValue != newValue) { | if (!std::isnan(internal->oldValue) && internal->oldValue != newValue) { | ||||
// Push ParamChange history action | // Push ParamChange history action | ||||
history::ParamChange* h = new history::ParamChange; | history::ParamChange* h = new history::ParamChange; | ||||
@@ -172,7 +172,7 @@ void ParamWidget::destroyTooltip() { | |||||
void ParamWidget::step() { | void ParamWidget::step() { | ||||
engine::ParamQuantity* pq = getParamQuantity(); | engine::ParamQuantity* pq = getParamQuantity(); | ||||
if (pq) { | if (pq) { | ||||
float value = pq->getSmoothValue(); | |||||
float value = pq->getValue(); | |||||
// Dispatch change event when the ParamQuantity value changes | // Dispatch change event when the ParamQuantity value changes | ||||
if (value != internal->lastValue) { | if (value != internal->lastValue) { | ||||
ChangeEvent eChange; | ChangeEvent eChange; | ||||
@@ -35,7 +35,7 @@ void SvgKnob::onChange(const ChangeEvent& e) { | |||||
// Re-transform the widget::TransformWidget | // Re-transform the widget::TransformWidget | ||||
engine::ParamQuantity* pq = getParamQuantity(); | engine::ParamQuantity* pq = getParamQuantity(); | ||||
if (pq) { | if (pq) { | ||||
float value = pq->getSmoothValue(); | |||||
float value = pq->getValue(); | |||||
float angle; | float angle; | ||||
if (!pq->isBounded()) { | if (!pq->isBounded()) { | ||||
// Number of rotations equals value for unbounded range | // Number of rotations equals value for unbounded range | ||||
@@ -57,7 +57,7 @@ void SvgSlider::onChange(const ChangeEvent& e) { | |||||
float v = 1.f; | float v = 1.f; | ||||
engine::ParamQuantity* pq = getParamQuantity(); | engine::ParamQuantity* pq = getParamQuantity(); | ||||
if (pq) { | if (pq) { | ||||
v = math::rescale(pq->getSmoothValue(), pq->getMinValue(), pq->getMaxValue(), 0.f, 1.f); | |||||
v = pq->getScaledValue(); | |||||
} | } | ||||
// Interpolate handle position | // Interpolate handle position | ||||
@@ -1060,19 +1060,19 @@ void Engine::setParamValue(Module* module, int paramId, float value) { | |||||
internal->smoothModule = NULL; | internal->smoothModule = NULL; | ||||
internal->smoothParamId = 0; | internal->smoothParamId = 0; | ||||
} | } | ||||
module->params[paramId].value = value; | |||||
module->params[paramId].setValue(value); | |||||
} | } | ||||
float Engine::getParamValue(Module* module, int paramId) { | float Engine::getParamValue(Module* module, int paramId) { | ||||
return module->params[paramId].value; | |||||
return module->params[paramId].getValue(); | |||||
} | } | ||||
void Engine::setParamSmoothValue(Module* module, int paramId, float value) { | void Engine::setParamSmoothValue(Module* module, int paramId, float value) { | ||||
// If another param is being smoothed, jump value | // If another param is being smoothed, jump value | ||||
if (internal->smoothModule && !(internal->smoothModule == module && internal->smoothParamId == paramId)) { | if (internal->smoothModule && !(internal->smoothModule == module && internal->smoothParamId == paramId)) { | ||||
internal->smoothModule->params[internal->smoothParamId].value = internal->smoothValue; | |||||
internal->smoothModule->params[internal->smoothParamId].setValue(internal->smoothValue); | |||||
} | } | ||||
internal->smoothParamId = paramId; | internal->smoothParamId = paramId; | ||||
internal->smoothValue = value; | internal->smoothValue = value; | ||||
@@ -1084,7 +1084,7 @@ void Engine::setParamSmoothValue(Module* module, int paramId, float value) { | |||||
float Engine::getParamSmoothValue(Module* module, int paramId) { | float Engine::getParamSmoothValue(Module* module, int paramId) { | ||||
if (internal->smoothModule == module && internal->smoothParamId == paramId) | if (internal->smoothModule == module && internal->smoothParamId == paramId) | ||||
return internal->smoothValue; | return internal->smoothValue; | ||||
return module->params[paramId].value; | |||||
return module->params[paramId].getValue(); | |||||
} | } | ||||
@@ -250,7 +250,7 @@ void Module::paramsFromJson(json_t* rootJ) { | |||||
json_t* valueJ = json_object_get(paramJ, "value"); | json_t* valueJ = json_object_get(paramJ, "value"); | ||||
if (valueJ) | if (valueJ) | ||||
pq->setValue(json_number_value(valueJ)); | |||||
pq->setDirectValue(json_number_value(valueJ)); | |||||
} | } | ||||
} | } | ||||
@@ -19,24 +19,26 @@ engine::Param* ParamQuantity::getParam() { | |||||
} | } | ||||
void ParamQuantity::setSmoothValue(float value) { | void ParamQuantity::setSmoothValue(float value) { | ||||
setValue(value); | |||||
} | |||||
float ParamQuantity::getSmoothValue() { | |||||
return getValue(); | |||||
} | |||||
void ParamQuantity::setDirectValue(float value) { | |||||
if (!module) | if (!module) | ||||
return; | return; | ||||
value = math::clampSafe(value, getMinValue(), getMaxValue()); | value = math::clampSafe(value, getMinValue(), getMaxValue()); | ||||
if (snapEnabled) | if (snapEnabled) | ||||
value = std::round(value); | value = std::round(value); | ||||
if (smoothEnabled) | |||||
APP->engine->setParamSmoothValue(module, paramId, value); | |||||
else | |||||
APP->engine->setParamValue(module, paramId, value); | |||||
APP->engine->setParamValue(module, paramId, value); | |||||
} | } | ||||
float ParamQuantity::getSmoothValue() { | |||||
float ParamQuantity::getDirectValue() { | |||||
if (!module) | if (!module) | ||||
return 0.f; | return 0.f; | ||||
if (smoothEnabled) | |||||
return APP->engine->getParamSmoothValue(module, paramId); | |||||
else | |||||
return APP->engine->getParamValue(module, paramId); | |||||
return APP->engine->getParamValue(module, paramId); | |||||
} | } | ||||
void ParamQuantity::setValue(float value) { | void ParamQuantity::setValue(float value) { | ||||
@@ -45,13 +47,19 @@ void ParamQuantity::setValue(float value) { | |||||
value = math::clampSafe(value, getMinValue(), getMaxValue()); | value = math::clampSafe(value, getMinValue(), getMaxValue()); | ||||
if (snapEnabled) | if (snapEnabled) | ||||
value = std::round(value); | value = std::round(value); | ||||
APP->engine->setParamValue(module, paramId, value); | |||||
if (smoothEnabled) | |||||
APP->engine->setParamSmoothValue(module, paramId, value); | |||||
else | |||||
APP->engine->setParamValue(module, paramId, value); | |||||
} | } | ||||
float ParamQuantity::getValue() { | float ParamQuantity::getValue() { | ||||
if (!module) | if (!module) | ||||
return 0.f; | return 0.f; | ||||
return APP->engine->getParamValue(module, paramId); | |||||
if (smoothEnabled) | |||||
return APP->engine->getParamSmoothValue(module, paramId); | |||||
else | |||||
return APP->engine->getParamValue(module, paramId); | |||||
} | } | ||||
float ParamQuantity::getMinValue() { | float ParamQuantity::getMinValue() { | ||||
@@ -67,8 +75,7 @@ float ParamQuantity::getDefaultValue() { | |||||
} | } | ||||
float ParamQuantity::getDisplayValue() { | float ParamQuantity::getDisplayValue() { | ||||
// We don't want the text to be smoothed (animated), so get the smooth target value. | |||||
float v = getSmoothValue(); | |||||
float v = getValue(); | |||||
if (displayBase == 0.f) { | if (displayBase == 0.f) { | ||||
// Linear | // Linear | ||||
// v is unchanged | // v is unchanged | ||||