29 QML_VALUE_TYPE (parameterRange)
32 enum class Type : std::uint8_t
76 enum class
Unit : std::uint8_t
98 : type_ (type),
minf_ (min), maxf_ (max),
99 zerof_ (std::clamp (zero, min, max)),
deff_ (std::clamp (def, min, max))
103 static ParameterRange make_toggle (
bool default_val)
105 return {
Type::Toggle, 0.f, 1.f, 0.f, default_val ? 1.f : 0.f };
107 static ParameterRange make_gain (
float max_val)
112 static ParameterRange make_enumeration (
113 std::vector<utils::Utf8String> labels,
114 size_t default_index = 0)
118 throw std::invalid_argument (
119 "Enumeration parameter requires at least one label");
121 if (default_index >= labels.size ())
123 throw std::invalid_argument (
124 "default_index out of range for enumeration labels");
126 const auto count =
static_cast<float> (labels.size ());
127 ParameterRange range{
129 static_cast<float> (default_index)
131 range.enum_labels_ = std::move (labels);
143 Q_INVOKABLE
size_t enumIndex (
float normalized_val)
const
145 const auto real = convertFrom0To1 (normalized_val);
147 const auto idx =
static_cast<size_t> (std::max (std::round (real), 0.f));
159 return convertTo0To1 (
static_cast<float> (index));
170 Q_INVOKABLE QString enumLabel (
int index)
const
172 if (index < 0 ||
static_cast<size_t> (index) >=
enum_labels_.size ())
174 return enum_label (
static_cast<size_t> (index)).to_qstring ();
177 template <utils::EnumType E>
float normalized_from_enum (E value)
const
180 const auto index =
static_cast<size_t> (value);
185 template <utils::EnumType E> E enum_value (
float normalized_val)
const
188 return static_cast<E
> (
enumIndex (normalized_val));
191 constexpr float clamp_to_range (
float val)
const
193 return std::clamp (val,
minf_, maxf_);
196 Q_INVOKABLE
float convertFrom0To1 (
float normalized_val)
const;
197 Q_INVOKABLE
float convertTo0To1 (
float real_val)
const;
199 Q_INVOKABLE
bool isToggled (
float normalized_val)
const
205 friend void to_json (nlohmann::json &j,
const ParameterRange &p);
206 friend void from_json (
const nlohmann::json &j, ParameterRange &p);
237 BOOST_DESCRIBE_CLASS (
252class ProcessorParameter
258 float baseValue READ baseValue WRITE setBaseValue NOTIFY baseValueChanged)
259 Q_PROPERTY (QString label READ label CONSTANT)
260 Q_PROPERTY (QString description READ description CONSTANT)
262 Q_PROPERTY (
bool automatable READ automatable CONSTANT)
267 struct UniqueId final
268 : type_safe::strong_typedef<UniqueId,
utils::Utf8String>,
269 type_safe::strong_typedef_op::equality_comparison<UniqueId>,
270 type_safe::strong_typedef_op::relational_comparison<UniqueId>
274 explicit UniqueId () =
default;
278 std::size_t hash ()
const {
return qHash (type_safe::get (*this).view ()); }
280 static_assert (std::regular<UniqueId>);
283 std::function<QPointer<ProcessorParameter> (
const UniqueId &unique_id)>;
290 QObject * parent =
nullptr);
306 std::function<std::optional<float> (units::sample_t sample_position)>;
312 QString label ()
const {
return label_.to_qstring (); }
313 QString description ()
const {
return description_->to_qstring (); }
314 bool automatable ()
const {
return automatable_; }
316 const auto &range ()
const {
return range_; }
318 float baseValue ()
const {
return base_value_.load (); }
319 void setBaseValue (
float newValue) [[clang::blocking]]
321 newValue = std::clamp (newValue, 0.f, 1.f);
322 if (qFuzzyCompare (base_value_, newValue))
324 base_value_ = newValue;
325 Q_EMIT baseValueChanged (newValue);
327 Q_INVOKABLE
void resetBaseValueToDefault ()
329 setBaseValue (range_.convertTo0To1 (range_.deff_));
331 Q_SIGNAL
void baseValueChanged (
float value);
337 Q_INVOKABLE
float currentValue ()
const {
return last_modulated_value_; }
347 return last_automated_value_.load ();
350 Q_INVOKABLE
void beginUserGesture ()
352 during_gesture_.store (
true);
353 Q_EMIT userGestureStarted ();
355 Q_INVOKABLE
void endUserGesture ()
357 during_gesture_.store (
false);
358 Q_EMIT userGestureFinished ();
360 Q_SIGNAL
void userGestureStarted ();
361 Q_SIGNAL
void userGestureFinished ();
380 const dsp::TempoMap &tempo_map)
noexcept override;
382 void prepare_for_processing_impl (
384 units::sample_rate_t sample_rate,
385 units::sample_u32_t max_block_length)
override;
392 automation_value_provider_ = provider;
394 void unset_automation_provider () { automation_value_provider_.reset (); }
396 PortUuidReference get_modulation_input_port_ref ()
const
398 return modulation_input_uuid_;
401 void set_description (utils::Utf8String descr)
403 description_ = std::move (descr);
406 void set_automatable (
bool automatable) { automatable_ = automatable; }
408 bool hidden ()
const {
return hidden_; }
410 const auto &get_unique_id ()
const {
return unique_id_; }
414 static constexpr auto kUniqueIdKey =
"uniqueId"sv;
415 static constexpr auto kRangeKey =
"range"sv;
416 static constexpr auto kLabelKey =
"label"sv;
417 static constexpr auto kSymbolKey =
"symbol"sv;
418 static constexpr auto kDescriptionKey =
"description"sv;
419 static constexpr auto kAutomatableKey =
"automatable"sv;
420 static constexpr auto kHiddenKey =
"hidden"sv;
421 static constexpr auto kBaseValueKey =
"baseValue"sv;
422 static constexpr auto kModulationSourcePortIdKey =
"modulationSourcePortId"sv;
423 friend void to_json (nlohmann::json &j,
const ProcessorParameter &p);
424 friend void from_json (
const nlohmann::json &j, ProcessorParameter &p);
440 ParameterRange range_;
443 utils::Utf8String label_;
448 std::atomic<float> base_value_;
455 std::atomic_bool during_gesture_;
464 std::atomic<float> last_automated_value_;
475 std::atomic<float> last_modulated_value_;
483 PortUuidReference modulation_input_uuid_;
486 dsp::CVPort * modulation_input_{};
493 std::optional<AutomationValueProvider> automation_value_provider_;
496 std::optional<utils::Utf8String> symbol_;
499 std::optional<utils::Utf8String> description_;
502 bool automatable_{
true };
507 BOOST_DESCRIBE_CLASS (
509 (utils::UuidIdentifiableObject<ProcessorParameter>),
516 modulation_input_uuid_,