ProcessorParameter.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright (c) 2021, kleines Filmröllchen <malu.bertsch@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include "AK/Forward.h"
  8. #include "LibGUI/Label.h"
  9. #include "Music.h"
  10. #include <AK/FixedPoint.h>
  11. #include <AK/Format.h>
  12. #include <AK/Types.h>
  13. #include <LibCore/Object.h>
  14. namespace LibDSP {
  15. using ParameterFixedPoint = FixedPoint<8, i64>;
  16. // Processors have modifiable parameters that should be presented to the UI in a uniform way without requiring the processor itself to implement custom interfaces.
  17. class ProcessorParameter {
  18. public:
  19. ProcessorParameter(String name)
  20. : m_name(move(name))
  21. {
  22. }
  23. String const& name() const { return m_name; }
  24. private:
  25. String const m_name;
  26. };
  27. namespace Detail {
  28. struct ProcessorParameterSetValueTag {
  29. explicit ProcessorParameterSetValueTag() = default;
  30. };
  31. template<typename ParameterT>
  32. class ProcessorParameterSingleValue : public ProcessorParameter {
  33. public:
  34. ProcessorParameterSingleValue(String name, ParameterT initial_value)
  35. : ProcessorParameter(move(name))
  36. , m_value(move(initial_value))
  37. {
  38. }
  39. operator ParameterT() const
  40. {
  41. return value();
  42. }
  43. operator double() const requires(IsSame<ParameterT, ParameterFixedPoint>)
  44. {
  45. return static_cast<double>(value());
  46. }
  47. ParameterT value() const { return m_value; };
  48. void set_value(ParameterT value)
  49. {
  50. set_value_sneaky(value, LibDSP::Detail::ProcessorParameterSetValueTag {});
  51. if (did_change_value)
  52. did_change_value(value);
  53. }
  54. // Use of this function is discouraged. It doesn't notify the value listener.
  55. void set_value_sneaky(ParameterT value, [[maybe_unused]] Detail::ProcessorParameterSetValueTag)
  56. {
  57. if (value != m_value)
  58. m_value = value;
  59. }
  60. Function<void(ParameterT const&)> did_change_value;
  61. protected:
  62. ParameterT m_value;
  63. };
  64. }
  65. class ProcessorBooleanParameter final : public Detail::ProcessorParameterSingleValue<bool> {
  66. public:
  67. ProcessorBooleanParameter(String name, bool initial_value)
  68. : Detail::ProcessorParameterSingleValue<bool>(move(name), move(initial_value))
  69. {
  70. }
  71. };
  72. class ProcessorRangeParameter final : public Detail::ProcessorParameterSingleValue<ParameterFixedPoint> {
  73. public:
  74. ProcessorRangeParameter(String name, ParameterFixedPoint min_value, ParameterFixedPoint max_value, ParameterFixedPoint initial_value)
  75. : Detail::ProcessorParameterSingleValue<ParameterFixedPoint>(move(name), move(initial_value))
  76. , m_min_value(move(min_value))
  77. , m_max_value(move(max_value))
  78. , m_default_value(move(initial_value))
  79. {
  80. VERIFY(initial_value <= max_value && initial_value >= min_value);
  81. }
  82. ProcessorRangeParameter(ProcessorRangeParameter const& to_copy)
  83. : ProcessorRangeParameter(to_copy.name(), to_copy.min_value(), to_copy.max_value(), to_copy.value())
  84. {
  85. }
  86. ParameterFixedPoint min_value() const { return m_min_value; }
  87. ParameterFixedPoint max_value() const { return m_max_value; }
  88. ParameterFixedPoint default_value() const { return m_default_value; }
  89. void set_value(ParameterFixedPoint value)
  90. {
  91. VERIFY(value <= m_max_value && value >= m_min_value);
  92. Detail::ProcessorParameterSingleValue<ParameterFixedPoint>::set_value(value);
  93. }
  94. private:
  95. double const m_min_value;
  96. double const m_max_value;
  97. double const m_default_value;
  98. };
  99. }
  100. template<>
  101. struct AK::Formatter<LibDSP::ProcessorRangeParameter> : AK::StandardFormatter {
  102. Formatter() = default;
  103. explicit Formatter(StandardFormatter formatter)
  104. : StandardFormatter(formatter)
  105. {
  106. }
  107. void format(FormatBuilder& builder, LibDSP::ProcessorRangeParameter value)
  108. {
  109. if (m_mode == Mode::Pointer) {
  110. Formatter<FlatPtr> formatter { *this };
  111. formatter.format(builder, reinterpret_cast<FlatPtr>(&value));
  112. return;
  113. }
  114. if (m_sign_mode != FormatBuilder::SignMode::Default)
  115. VERIFY_NOT_REACHED();
  116. if (m_alternative_form)
  117. VERIFY_NOT_REACHED();
  118. if (m_zero_pad)
  119. VERIFY_NOT_REACHED();
  120. if (m_mode != Mode::Default)
  121. VERIFY_NOT_REACHED();
  122. if (m_width.has_value() && m_precision.has_value())
  123. VERIFY_NOT_REACHED();
  124. m_width = m_width.value_or(0);
  125. m_precision = m_precision.value_or(NumericLimits<size_t>::max());
  126. builder.put_literal(String::formatted("[{} - {}]: {}", value.min_value(), value.max_value(), value.value()));
  127. }
  128. };