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.

131 lines
2.5KB

  1. #include <tinyexpr.h>
  2. #include <Quantity.hpp>
  3. #include <string.hpp>
  4. namespace rack {
  5. float Quantity::getDisplayValue() {
  6. return getValue();
  7. }
  8. void Quantity::setDisplayValue(float displayValue) {
  9. setValue(displayValue);
  10. }
  11. int Quantity::getDisplayPrecision() {
  12. return 5;
  13. }
  14. std::string Quantity::getDisplayValueString() {
  15. float v = getDisplayValue();
  16. if (std::isnan(v))
  17. return "NaN";
  18. return string::f("%.*g", getDisplayPrecision(), math::normalizeZero(v));
  19. }
  20. void Quantity::setDisplayValueString(std::string s) {
  21. static const double inf = INFINITY;
  22. static te_variable vars[] = {
  23. {"inf", &inf, TE_VARIABLE, NULL},
  24. };
  25. te_expr* expr = te_compile(s.c_str(), vars, LENGTHOF(vars), NULL);
  26. if (!expr)
  27. return;
  28. double result = te_eval(expr);
  29. te_free(expr);
  30. if (std::isnan(result))
  31. return;
  32. setDisplayValue(result);
  33. }
  34. std::string Quantity::getString() {
  35. std::string s;
  36. std::string label = getLabel();
  37. std::string valueString = getDisplayValueString() + getUnit();
  38. s += label;
  39. if (label != "" && valueString != "")
  40. s += ": ";
  41. s += valueString;
  42. return s;
  43. }
  44. void Quantity::reset() {
  45. setValue(getDefaultValue());
  46. }
  47. void Quantity::randomize() {
  48. if (isBounded())
  49. setScaledValue(random::uniform());
  50. }
  51. bool Quantity::isMin() {
  52. return getValue() <= getMinValue();
  53. }
  54. bool Quantity::isMax() {
  55. return getValue() >= getMaxValue();
  56. }
  57. void Quantity::setMin() {
  58. setValue(getMinValue());
  59. }
  60. void Quantity::setMax() {
  61. setValue(getMaxValue());
  62. }
  63. void Quantity::toggle() {
  64. setValue(isMin() ? getMaxValue() : getMinValue());
  65. }
  66. void Quantity::moveValue(float deltaValue) {
  67. setValue(getValue() + deltaValue);
  68. }
  69. float Quantity::getRange() {
  70. return getMaxValue() - getMinValue();
  71. }
  72. bool Quantity::isBounded() {
  73. return std::isfinite(getMinValue()) && std::isfinite(getMaxValue());
  74. }
  75. float Quantity::toScaled(float value) {
  76. if (!isBounded())
  77. return value;
  78. else if (getMinValue() == getMaxValue())
  79. return 0.f;
  80. else
  81. return math::rescale(value, getMinValue(), getMaxValue(), 0.f, 1.f);
  82. }
  83. float Quantity::fromScaled(float scaledValue) {
  84. if (!isBounded())
  85. return scaledValue;
  86. else
  87. return math::rescale(scaledValue, 0.f, 1.f, getMinValue(), getMaxValue());
  88. }
  89. void Quantity::setScaledValue(float scaledValue) {
  90. setValue(fromScaled(scaledValue));
  91. }
  92. float Quantity::getScaledValue() {
  93. return toScaled(getValue());
  94. }
  95. void Quantity::moveScaledValue(float deltaScaledValue) {
  96. if (!isBounded())
  97. moveValue(deltaScaledValue);
  98. else
  99. moveValue(deltaScaledValue * getRange());
  100. }
  101. } // namespace rack