24 enum class Type : std::uint8_t
67 enum class Unit : std::uint8_t
85 constexpr std::array<std::u8string_view, 8> port_unit_strings = {
86 u8
"none", u8
"Hz", u8
"MHz", u8
"dB", u8
"°", u8
"s", u8
"ms", u8
"μs",
88 return port_unit_strings.at (ENUM_VALUE_TO_INT (unit));
92 ParameterRange () =
default;
94 ParameterRange (
Type type,
float min,
float max,
float zero = 0.f,
float def = 0.f)
95 : type_ (type),
minf_ (min), maxf_ (max),
96 zerof_ (std::clamp (zero, min, max)),
deff_ (std::clamp (def, min, max))
100 static ParameterRange make_toggle (
bool default_val)
102 return {
Type::Toggle, 0.f, 1.f, 0.f, default_val ? 1.f : 0.f };
104 static ParameterRange make_gain (
float max_val)
109 constexpr float clamp_to_range (
float val)
const
111 return std::clamp (val,
minf_, maxf_);
114 Q_INVOKABLE
float convertFrom0To1 (
float normalized_val)
const
126 return minf * std::pow (maxf / minf, normalized_val);
130 return normalized_val >= 0.001f ? 1.f : 0.f;
134 return utils::math::get_amp_val_from_fader (normalized_val);
137 return minf_ + (normalized_val * (maxf_ -
minf_));
140 Q_INVOKABLE
float convertTo0To1 (
float real_val)
const
152 return std::log (real_val / minf) / std::log (maxf / minf);
160 return utils::math::get_fader_val_from_amp (real_val);
163 const auto sizef = maxf_ -
minf_;
164 return (sizef - (maxf_ - real_val)) / sizef;
167 bool is_toggled (
float normalized_val)
const
173 NLOHMANN_DEFINE_TYPE_INTRUSIVE (
206 BOOST_DESCRIBE_CLASS (
221class ProcessorParameter
228 float baseValue READ baseValue WRITE setBaseValue NOTIFY baseValueChanged)
229 Q_PROPERTY (QString label READ label CONSTANT)
230 Q_PROPERTY (QString description READ description CONSTANT)
232 Q_PROPERTY (
bool automatable READ automatable CONSTANT)
237 struct UniqueId final
238 : type_safe::strong_typedef<UniqueId,
utils::Utf8String>,
239 type_safe::strong_typedef_op::equality_comparison<UniqueId>,
240 type_safe::strong_typedef_op::relational_comparison<UniqueId>
244 explicit UniqueId () =
default;
248 std::size_t hash ()
const {
return qHash (type_safe::get (*this).view ()); }
250 static_assert (std::regular<UniqueId>);
253 std::function<QPointer<ProcessorParameter> (
const UniqueId &unique_id)>;
256 PortRegistry &port_registry,
260 QObject * parent =
nullptr);
276 std::function<std::optional<float> (units::sample_t sample_position)>;
282 QString label ()
const {
return label_.to_qstring (); }
283 QString description ()
const {
return description_->to_qstring (); }
284 bool automatable ()
const {
return automatable_; }
286 ParameterRange range ()
const {
return range_; }
288 float baseValue ()
const {
return base_value_.load (); }
289 void setBaseValue (
float newValue) [[clang::blocking]]
291 newValue = std::clamp (newValue, 0.f, 1.f);
292 if (qFuzzyCompare (base_value_, newValue))
294 base_value_ = newValue;
295 Q_EMIT baseValueChanged (newValue);
297 Q_INVOKABLE
void resetBaseValueToDefault ()
299 setBaseValue (range_.convertTo0To1 (range_.deff_));
301 Q_SIGNAL
void baseValueChanged (
float value);
307 Q_INVOKABLE
float currentValue ()
const {
return last_modulated_value_; }
317 return last_automated_value_.load ();
320 Q_INVOKABLE
void beginUserGesture ()
322 during_gesture_.store (
true);
323 Q_EMIT userGestureStarted ();
325 Q_INVOKABLE
void endUserGesture ()
327 during_gesture_.store (
false);
328 Q_EMIT userGestureFinished ();
330 Q_SIGNAL
void userGestureStarted ();
331 Q_SIGNAL
void userGestureFinished ();
353 units::sample_rate_t sample_rate,
361 automation_value_provider_ = provider;
363 void unset_automation_provider () { automation_value_provider_.reset (); }
365 PortUuidReference get_modulation_input_port_ref ()
const
367 return modulation_input_uuid_;
370 void set_description (utils::Utf8String descr)
372 description_ = std::move (descr);
375 void set_automatable (
bool automatable) { automatable_ = automatable; }
377 const auto &get_unique_id ()
const {
return unique_id_; }
384 static constexpr auto kUniqueIdKey =
"uniqueId"sv;
388 static constexpr auto kLabelKey =
"label"sv;
393 static constexpr auto kBaseValueKey =
"baseValue"sv;
394 static constexpr auto kModulationSourcePortIdKey =
"modulationSourcePortId"sv;
395 friend void to_json (nlohmann::json &j,
const ProcessorParameter &p)
397 j[kUniqueIdKey] = p.unique_id_;
398 j[kLabelKey] = p.label_;
399 j[kBaseValueKey] = p.base_value_.load ();
400 j[kModulationSourcePortIdKey] = p.modulation_input_uuid_;
402 friend void from_json (
const nlohmann::json &j, ProcessorParameter &p)
404 j.at (kUniqueIdKey).get_to (p.unique_id_);
405 j.at (kLabelKey).get_to (p.label_);
407 j.at (kBaseValueKey).get_to (base_val);
408 p.base_value_.store (base_val);
409 j.at (kModulationSourcePortIdKey).get_to (p.modulation_input_uuid_);
418 ParameterRange range_;
421 utils::Utf8String label_;
426 std::atomic<float> base_value_;
433 std::atomic_bool during_gesture_;
442 std::atomic<float> last_automated_value_;
453 std::atomic<float> last_modulated_value_;
461 PortUuidReference modulation_input_uuid_;
464 dsp::CVPort * modulation_input_{};
471 std::optional<AutomationValueProvider> automation_value_provider_;
474 std::optional<utils::Utf8String> symbol_;
477 std::optional<utils::Utf8String> description_;
480 bool automatable_{
true };
485 BOOST_DESCRIBE_CLASS (
487 (utils::UuidIdentifiableObject<ProcessorParameter>),
494 modulation_input_uuid_,
520class ProcessorParameterRegistry
522 OwningObjectRegistry<ProcessorParameterPtrVariant, ProcessorParameter>
525 ProcessorParameterRegistry (
526 dsp::PortRegistry &port_registry,
527 QObject * parent =
nullptr)
529 ProcessorParameterPtrVariant,
531 port_registry_ (port_registry)
538 const auto &map = get_hash_map ();
539 for (
const auto &kv : map)
541 if (std::get<ProcessorParameter *> (kv.second)->get_unique_id () ==
id)
543 return std::get<ProcessorParameter *> (kv.second);
552 auto * val = find_by_unique_id (
id);
553 if (val ==
nullptr) [[unlikely]]
555 throw std::runtime_error (
556 fmt::format (
"Processor Parameter with unique id {} not found",
id));
562 struct ProcessorParameterRegistryBuilder
564 ProcessorParameterRegistryBuilder (dsp::PortRegistry &port_registry)
565 : port_registry_ (port_registry)
569 template <
typename T> std::unique_ptr<T> build ()
const
571 return std::make_unique<T> (
576 dsp::PortRegistry &port_registry_;
580 from_json (
const nlohmann::json &j, ProcessorParameterRegistry ®)
582 from_json_with_builder (
583 j, reg, ProcessorParameterRegistryBuilder{ reg.port_registry_ });
587 dsp::PortRegistry &port_registry_;