ProcessorParameter.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Copyright (c) 2021, kleines Filmröllchen <filmroellchen@serenityos.org>
  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. enum class Logarithmic : bool {
  24. No,
  25. Yes
  26. };
  27. // Processors have modifiable parameters that should be presented to the UI in a uniform way without requiring the processor itself to implement custom interfaces.
  28. class ProcessorParameter {
  29. public:
  30. ProcessorParameter(String name, ParameterType type)
  31. : m_name(move(name))
  32. , m_type(type)
  33. {
  34. }
  35. String const& name() const { return m_name; }
  36. ParameterType type() const { return m_type; }
  37. private:
  38. String const m_name;
  39. ParameterType const m_type;
  40. };
  41. namespace Detail {
  42. struct ProcessorParameterSetValueTag {
  43. explicit ProcessorParameterSetValueTag() = default;
  44. };
  45. template<typename ParameterT>
  46. class ProcessorParameterSingleValue : public ProcessorParameter {
  47. public:
  48. ProcessorParameterSingleValue(String name, ParameterType type, ParameterT initial_value)
  49. : ProcessorParameter(move(name), type)
  50. , m_value(move(initial_value))
  51. {
  52. }
  53. operator ParameterT() const
  54. {
  55. return value();
  56. }
  57. operator double() const requires(IsSame<ParameterT, ParameterFixedPoint>)
  58. {
  59. return static_cast<double>(value());
  60. }
  61. ParameterT value() const { return m_value; };
  62. void set_value(ParameterT value)
  63. {
  64. set_value_sneaky(value, LibDSP::Detail::ProcessorParameterSetValueTag {});
  65. if (did_change_value)
  66. did_change_value(value);
  67. }
  68. // Use of this function is discouraged. It doesn't notify the value listener.
  69. void set_value_sneaky(ParameterT value, [[maybe_unused]] Detail::ProcessorParameterSetValueTag)
  70. {
  71. if (value != m_value)
  72. m_value = value;
  73. }
  74. Function<void(ParameterT const&)> did_change_value;
  75. protected:
  76. ParameterT m_value;
  77. };
  78. }
  79. class ProcessorBooleanParameter final : public Detail::ProcessorParameterSingleValue<bool> {
  80. public:
  81. ProcessorBooleanParameter(String name, bool initial_value)
  82. : Detail::ProcessorParameterSingleValue<bool>(move(name), ParameterType::Boolean, move(initial_value))
  83. {
  84. }
  85. };
  86. class ProcessorRangeParameter final : public Detail::ProcessorParameterSingleValue<ParameterFixedPoint> {
  87. public:
  88. ProcessorRangeParameter(String name, ParameterFixedPoint min_value, ParameterFixedPoint max_value, ParameterFixedPoint initial_value, Logarithmic logarithmic)
  89. : Detail::ProcessorParameterSingleValue<ParameterFixedPoint>(move(name), ParameterType::Range, move(initial_value))
  90. , m_min_value(move(min_value))
  91. , m_max_value(move(max_value))
  92. , m_default_value(move(initial_value))
  93. , m_logarithmic(logarithmic)
  94. {
  95. VERIFY(initial_value <= max_value && initial_value >= min_value);
  96. }
  97. ProcessorRangeParameter(ProcessorRangeParameter const& to_copy)
  98. : ProcessorRangeParameter(to_copy.name(), to_copy.min_value(), to_copy.max_value(), to_copy.value(), to_copy.is_logarithmic())
  99. {
  100. }
  101. ParameterFixedPoint min_value() const { return m_min_value; }
  102. ParameterFixedPoint max_value() const { return m_max_value; }
  103. ParameterFixedPoint range() const { return m_max_value - m_min_value; }
  104. constexpr Logarithmic is_logarithmic() const { return m_logarithmic; }
  105. ParameterFixedPoint default_value() const { return m_default_value; }
  106. void set_value(ParameterFixedPoint value)
  107. {
  108. VERIFY(value <= m_max_value && value >= m_min_value);
  109. Detail::ProcessorParameterSingleValue<ParameterFixedPoint>::set_value(value);
  110. }
  111. private:
  112. double const m_min_value;
  113. double const m_max_value;
  114. double const m_default_value;
  115. Logarithmic const m_logarithmic;
  116. };
  117. template<typename EnumT>
  118. requires(IsEnum<EnumT>) class ProcessorEnumParameter final : public Detail::ProcessorParameterSingleValue<EnumT> {
  119. public:
  120. ProcessorEnumParameter(String name, EnumT initial_value)
  121. : Detail::ProcessorParameterSingleValue<EnumT>(move(name), ParameterType::Enum, initial_value)
  122. {
  123. }
  124. };
  125. }
  126. template<>
  127. struct AK::Formatter<LibDSP::ProcessorRangeParameter> : AK::StandardFormatter {
  128. Formatter() = default;
  129. explicit Formatter(StandardFormatter formatter)
  130. : StandardFormatter(formatter)
  131. {
  132. }
  133. ErrorOr<void> format(FormatBuilder& builder, LibDSP::ProcessorRangeParameter value)
  134. {
  135. if (m_mode == Mode::Pointer) {
  136. Formatter<FlatPtr> formatter { *this };
  137. return formatter.format(builder, reinterpret_cast<FlatPtr>(&value));
  138. }
  139. if (m_sign_mode != FormatBuilder::SignMode::Default)
  140. VERIFY_NOT_REACHED();
  141. if (m_alternative_form)
  142. VERIFY_NOT_REACHED();
  143. if (m_zero_pad)
  144. VERIFY_NOT_REACHED();
  145. if (m_mode != Mode::Default)
  146. VERIFY_NOT_REACHED();
  147. if (m_width.has_value() && m_precision.has_value())
  148. VERIFY_NOT_REACHED();
  149. m_width = m_width.value_or(0);
  150. m_precision = m_precision.value_or(NumericLimits<size_t>::max());
  151. TRY(builder.put_literal(String::formatted("[{} - {}]: {}", value.min_value(), value.max_value(), value.value())));
  152. return {};
  153. }
  154. };