ProcessorParameter.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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/FixedPoint.h>
  8. #include <AK/Format.h>
  9. #include <AK/Forward.h>
  10. #include <AK/Types.h>
  11. #include <LibCore/Object.h>
  12. #include <LibDSP/Music.h>
  13. namespace LibDSP {
  14. using ParameterFixedPoint = FixedPoint<8, i64>;
  15. // Identifies the different kinds of parameters.
  16. // Note that achieving parameter type identification is NOT possible with typeid().
  17. enum class ParameterType : u8 {
  18. Invalid = 0,
  19. Range,
  20. Enum,
  21. Boolean,
  22. };
  23. // Processors have modifiable parameters that should be presented to the UI in a uniform way without requiring the processor itself to implement custom interfaces.
  24. class ProcessorParameter {
  25. public:
  26. ProcessorParameter(String name, ParameterType type)
  27. : m_name(move(name))
  28. , m_type(type)
  29. {
  30. }
  31. String const& name() const { return m_name; }
  32. ParameterType type() const { return m_type; }
  33. private:
  34. String const m_name;
  35. ParameterType const m_type;
  36. };
  37. namespace Detail {
  38. struct ProcessorParameterSetValueTag {
  39. explicit ProcessorParameterSetValueTag() = default;
  40. };
  41. template<typename ParameterT>
  42. class ProcessorParameterSingleValue : public ProcessorParameter {
  43. public:
  44. ProcessorParameterSingleValue(String name, ParameterType type, ParameterT initial_value)
  45. : ProcessorParameter(move(name), type)
  46. , m_value(move(initial_value))
  47. {
  48. }
  49. operator ParameterT() const
  50. {
  51. return value();
  52. }
  53. operator double() const requires(IsSame<ParameterT, ParameterFixedPoint>)
  54. {
  55. return static_cast<double>(value());
  56. }
  57. ParameterT value() const { return m_value; };
  58. void set_value(ParameterT value)
  59. {
  60. set_value_sneaky(value, LibDSP::Detail::ProcessorParameterSetValueTag {});
  61. if (did_change_value)
  62. did_change_value(value);
  63. }
  64. // Use of this function is discouraged. It doesn't notify the value listener.
  65. void set_value_sneaky(ParameterT value, [[maybe_unused]] Detail::ProcessorParameterSetValueTag)
  66. {
  67. if (value != m_value)
  68. m_value = value;
  69. }
  70. Function<void(ParameterT const&)> did_change_value;
  71. protected:
  72. ParameterT m_value;
  73. };
  74. }
  75. class ProcessorBooleanParameter final : public Detail::ProcessorParameterSingleValue<bool> {
  76. public:
  77. ProcessorBooleanParameter(String name, bool initial_value)
  78. : Detail::ProcessorParameterSingleValue<bool>(move(name), ParameterType::Boolean, move(initial_value))
  79. {
  80. }
  81. };
  82. class ProcessorRangeParameter final : public Detail::ProcessorParameterSingleValue<ParameterFixedPoint> {
  83. public:
  84. ProcessorRangeParameter(String name, ParameterFixedPoint min_value, ParameterFixedPoint max_value, ParameterFixedPoint initial_value)
  85. : Detail::ProcessorParameterSingleValue<ParameterFixedPoint>(move(name), ParameterType::Range, move(initial_value))
  86. , m_min_value(move(min_value))
  87. , m_max_value(move(max_value))
  88. , m_default_value(move(initial_value))
  89. {
  90. VERIFY(initial_value <= max_value && initial_value >= min_value);
  91. }
  92. ProcessorRangeParameter(ProcessorRangeParameter const& to_copy)
  93. : ProcessorRangeParameter(to_copy.name(), to_copy.min_value(), to_copy.max_value(), to_copy.value())
  94. {
  95. }
  96. ParameterFixedPoint min_value() const { return m_min_value; }
  97. ParameterFixedPoint max_value() const { return m_max_value; }
  98. ParameterFixedPoint default_value() const { return m_default_value; }
  99. void set_value(ParameterFixedPoint value)
  100. {
  101. VERIFY(value <= m_max_value && value >= m_min_value);
  102. Detail::ProcessorParameterSingleValue<ParameterFixedPoint>::set_value(value);
  103. }
  104. private:
  105. double const m_min_value;
  106. double const m_max_value;
  107. double const m_default_value;
  108. };
  109. template<typename EnumT>
  110. requires(IsEnum<EnumT>) class ProcessorEnumParameter final : public Detail::ProcessorParameterSingleValue<EnumT> {
  111. public:
  112. ProcessorEnumParameter(String name, EnumT initial_value)
  113. : Detail::ProcessorParameterSingleValue<EnumT>(move(name), ParameterType::Enum, initial_value)
  114. {
  115. }
  116. };
  117. }
  118. template<>
  119. struct AK::Formatter<LibDSP::ProcessorRangeParameter> : AK::StandardFormatter {
  120. Formatter() = default;
  121. explicit Formatter(StandardFormatter formatter)
  122. : StandardFormatter(formatter)
  123. {
  124. }
  125. ErrorOr<void> format(FormatBuilder& builder, LibDSP::ProcessorRangeParameter value)
  126. {
  127. if (m_mode == Mode::Pointer) {
  128. Formatter<FlatPtr> formatter { *this };
  129. return formatter.format(builder, reinterpret_cast<FlatPtr>(&value));
  130. }
  131. if (m_sign_mode != FormatBuilder::SignMode::Default)
  132. VERIFY_NOT_REACHED();
  133. if (m_alternative_form)
  134. VERIFY_NOT_REACHED();
  135. if (m_zero_pad)
  136. VERIFY_NOT_REACHED();
  137. if (m_mode != Mode::Default)
  138. VERIFY_NOT_REACHED();
  139. if (m_width.has_value() && m_precision.has_value())
  140. VERIFY_NOT_REACHED();
  141. m_width = m_width.value_or(0);
  142. m_precision = m_precision.value_or(NumericLimits<size_t>::max());
  143. TRY(builder.put_literal(String::formatted("[{} - {}]: {}", value.min_value(), value.max_value(), value.value())));
  144. return {};
  145. }
  146. };