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.

127 lines
2.4KB

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