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.

200 lines
4.2KB

  1. #include <algorithm>
  2. #include <engine/ParamQuantity.hpp>
  3. #include <context.hpp>
  4. #include <engine/Engine.hpp>
  5. #include <string.hpp>
  6. namespace rack {
  7. namespace engine {
  8. engine::Param* ParamQuantity::getParam() {
  9. if (!module)
  10. return NULL;
  11. if (!(0 <= paramId && paramId < (int) module->params.size()))
  12. return NULL;
  13. return &module->params[paramId];
  14. }
  15. void ParamQuantity::setSmoothValue(float value) {
  16. if (!module)
  17. return;
  18. value = math::clampSafe(value, getMinValue(), getMaxValue());
  19. if (snapEnabled)
  20. value = std::round(value);
  21. if (smoothEnabled)
  22. APP->engine->setParamSmoothValue(module, paramId, value);
  23. else
  24. APP->engine->setParamValue(module, paramId, value);
  25. }
  26. float ParamQuantity::getSmoothValue() {
  27. if (!module)
  28. return 0.f;
  29. if (smoothEnabled)
  30. return APP->engine->getParamSmoothValue(module, paramId);
  31. else
  32. return APP->engine->getParamValue(module, paramId);
  33. }
  34. void ParamQuantity::setValue(float value) {
  35. if (!module)
  36. return;
  37. value = math::clampSafe(value, getMinValue(), getMaxValue());
  38. if (snapEnabled)
  39. value = std::round(value);
  40. APP->engine->setParamValue(module, paramId, value);
  41. }
  42. float ParamQuantity::getValue() {
  43. if (!module)
  44. return 0.f;
  45. return APP->engine->getParamValue(module, paramId);
  46. }
  47. float ParamQuantity::getMinValue() {
  48. return minValue;
  49. }
  50. float ParamQuantity::getMaxValue() {
  51. return maxValue;
  52. }
  53. float ParamQuantity::getDefaultValue() {
  54. return defaultValue;
  55. }
  56. float ParamQuantity::getDisplayValue() {
  57. // We don't want the text to be smoothed (animated), so get the smooth target value.
  58. float v = getSmoothValue();
  59. if (displayBase == 0.f) {
  60. // Linear
  61. // v is unchanged
  62. }
  63. else if (displayBase < 0.f) {
  64. // Logarithmic
  65. v = std::log(v) / std::log(-displayBase);
  66. }
  67. else {
  68. // Exponential
  69. v = std::pow(displayBase, v);
  70. }
  71. return v * displayMultiplier + displayOffset;
  72. }
  73. void ParamQuantity::setDisplayValue(float displayValue) {
  74. // Handle displayOffset
  75. float v = displayValue - displayOffset;
  76. // Handle displayMultiplier
  77. if (displayMultiplier == 0.f)
  78. v = 0.f;
  79. else
  80. v /= displayMultiplier;
  81. // Handle displayBase
  82. if (displayBase == 0.f) {
  83. // Linear
  84. // v is unchanged
  85. }
  86. else if (displayBase < 0.f) {
  87. // Logarithmic
  88. v = std::pow(-displayBase, v);
  89. }
  90. else {
  91. // Exponential
  92. v = std::log(v) / std::log(displayBase);
  93. }
  94. if (std::isnan(v))
  95. return;
  96. // Set the value directly without smoothing
  97. setValue(v);
  98. }
  99. int ParamQuantity::getDisplayPrecision() {
  100. return displayPrecision;
  101. }
  102. std::string ParamQuantity::getDisplayValueString() {
  103. return Quantity::getDisplayValueString();
  104. }
  105. void ParamQuantity::setDisplayValueString(std::string s) {
  106. Quantity::setDisplayValueString(s);
  107. }
  108. std::string ParamQuantity::getLabel() {
  109. if (name == "")
  110. return string::f("#%d", paramId + 1);
  111. return name;
  112. }
  113. std::string ParamQuantity::getUnit() {
  114. return unit;
  115. }
  116. void ParamQuantity::reset() {
  117. Quantity::reset();
  118. }
  119. void ParamQuantity::randomize() {
  120. if (!isBounded())
  121. return;
  122. if (snapEnabled) {
  123. // Randomize inclusive of the maximum value
  124. float value = math::rescale(random::uniform(), 0.f, 1.f, getMinValue(), getMaxValue() + 1.f);
  125. value = std::floor(value);
  126. setValue(value);
  127. }
  128. else {
  129. // Same as Quantity::randomize
  130. setScaledValue(random::uniform());
  131. }
  132. }
  133. std::string ParamQuantity::getDescription() {
  134. return description;
  135. }
  136. json_t* ParamQuantity::toJson() {
  137. json_t* rootJ = json_object();
  138. json_object_set_new(rootJ, "value", json_real(getValue()));
  139. return rootJ;
  140. }
  141. void ParamQuantity::fromJson(json_t* rootJ) {
  142. json_t* valueJ = json_object_get(rootJ, "value");
  143. if (valueJ)
  144. setValue(json_number_value(valueJ));
  145. }
  146. std::string SwitchQuantity::getDisplayValueString() {
  147. int index = (int) std::floor(getValue() - getMinValue());
  148. if (!(0 <= index && index < (int) labels.size()))
  149. return "";
  150. return labels[index];
  151. }
  152. void SwitchQuantity::setDisplayValueString(std::string s) {
  153. // Find label that matches string, case insensitive.
  154. auto it = std::find_if(labels.begin(), labels.end(), [&](const std::string& a) {
  155. return string::lowercase(a) == string::lowercase(s);
  156. });
  157. if (it == labels.end())
  158. return;
  159. int index = std::distance(labels.begin(), it);
  160. setValue(getMinValue() + index);
  161. }
  162. } // namespace engine
  163. } // namespace rack