25 enum class Type : std::uint8_t
68 enum class Unit : std::uint8_t
86 constexpr std::array<std::u8string_view, 8> port_unit_strings = {
87 u8
"none", u8
"Hz", u8
"MHz", u8
"dB", u8
"°", u8
"s", u8
"ms", u8
"μs",
89 return port_unit_strings.at (ENUM_VALUE_TO_INT (unit));
93 ParameterRange () =
default;
95 ParameterRange (
Type type,
float min,
float max,
float zero = 0.f,
float def = 0.f)
96 : type_ (type),
minf_ (min), maxf_ (max),
97 zerof_ (std::clamp (zero, min, max)),
deff_ (std::clamp (def, min, max))
101 static ParameterRange make_toggle (
bool default_val)
103 return {
Type::Toggle, 0.f, 1.f, 0.f, default_val ? 1.f : 0.f };
105 static ParameterRange make_gain (
float max_val)
110 constexpr float clamp_to_range (
float val)
const
112 return std::clamp (val,
minf_, maxf_);
115 Q_INVOKABLE
float convertFrom0To1 (
float normalized_val)
const
127 return minf * std::pow (maxf / minf, normalized_val);
131 return normalized_val >= 0.001f ? 1.f : 0.f;
135 return utils::math::get_amp_val_from_fader (normalized_val);
138 return minf_ + (normalized_val * (maxf_ -
minf_));
141 Q_INVOKABLE
float convertTo0To1 (
float real_val)
const
153 return std::log (real_val / minf) / std::log (maxf / minf);
161 return utils::math::get_fader_val_from_amp (real_val);
164 const auto sizef = maxf_ -
minf_;
165 return (sizef - (maxf_ - real_val)) / sizef;
168 bool is_toggled (
float normalized_val)
const
174 friend void to_json (nlohmann::json &j,
const ParameterRange &p);
175 friend void from_json (
const nlohmann::json &j, ParameterRange &p);
201 BOOST_DESCRIBE_CLASS (
216class ProcessorParameter
223 float baseValue READ baseValue WRITE setBaseValue NOTIFY baseValueChanged)
224 Q_PROPERTY (QString label READ label CONSTANT)
225 Q_PROPERTY (QString description READ description CONSTANT)
227 Q_PROPERTY (
bool automatable READ automatable CONSTANT)
232 struct UniqueId final
233 : type_safe::strong_typedef<UniqueId,
utils::Utf8String>,
234 type_safe::strong_typedef_op::equality_comparison<UniqueId>,
235 type_safe::strong_typedef_op::relational_comparison<UniqueId>
239 explicit UniqueId () =
default;
243 std::size_t hash ()
const {
return qHash (type_safe::get (*this).view ()); }
245 static_assert (std::regular<UniqueId>);
248 std::function<QPointer<ProcessorParameter> (
const UniqueId &unique_id)>;
251 PortRegistry &port_registry,
255 QObject * parent =
nullptr);
271 std::function<std::optional<float> (units::sample_t sample_position)>;
277 QString label ()
const {
return label_.to_qstring (); }
278 QString description ()
const {
return description_->to_qstring (); }
279 bool automatable ()
const {
return automatable_; }
281 ParameterRange range ()
const {
return range_; }
283 float baseValue ()
const {
return base_value_.load (); }
284 void setBaseValue (
float newValue) [[clang::blocking]]
286 newValue = std::clamp (newValue, 0.f, 1.f);
287 if (qFuzzyCompare (base_value_, newValue))
289 base_value_ = newValue;
290 Q_EMIT baseValueChanged (newValue);
292 Q_INVOKABLE
void resetBaseValueToDefault ()
294 setBaseValue (range_.convertTo0To1 (range_.deff_));
296 Q_SIGNAL
void baseValueChanged (
float value);
302 Q_INVOKABLE
float currentValue ()
const {
return last_modulated_value_; }
312 return last_automated_value_.load ();
315 Q_INVOKABLE
void beginUserGesture ()
317 during_gesture_.store (
true);
318 Q_EMIT userGestureStarted ();
320 Q_INVOKABLE
void endUserGesture ()
322 during_gesture_.store (
false);
323 Q_EMIT userGestureFinished ();
325 Q_SIGNAL
void userGestureStarted ();
326 Q_SIGNAL
void userGestureFinished ();
345 const dsp::TempoMap &tempo_map)
noexcept override;
349 units::sample_rate_t sample_rate,
357 automation_value_provider_ = provider;
359 void unset_automation_provider () { automation_value_provider_.reset (); }
361 PortUuidReference get_modulation_input_port_ref ()
const
363 return modulation_input_uuid_;
366 void set_description (utils::Utf8String descr)
368 description_ = std::move (descr);
371 void set_automatable (
bool automatable) { automatable_ = automatable; }
373 const auto &get_unique_id ()
const {
return unique_id_; }
380 static constexpr auto kUniqueIdKey =
"uniqueId"sv;
384 static constexpr auto kLabelKey =
"label"sv;
389 static constexpr auto kBaseValueKey =
"baseValue"sv;
390 static constexpr auto kModulationSourcePortIdKey =
"modulationSourcePortId"sv;
391 friend void to_json (nlohmann::json &j,
const ProcessorParameter &p);
392 friend void from_json (
const nlohmann::json &j, ProcessorParameter &p);
400 ParameterRange range_;
403 utils::Utf8String label_;
408 std::atomic<float> base_value_;
415 std::atomic_bool during_gesture_;
424 std::atomic<float> last_automated_value_;
435 std::atomic<float> last_modulated_value_;
443 PortUuidReference modulation_input_uuid_;
446 dsp::CVPort * modulation_input_{};
453 std::optional<AutomationValueProvider> automation_value_provider_;
456 std::optional<utils::Utf8String> symbol_;
459 std::optional<utils::Utf8String> description_;
462 bool automatable_{
true };
467 BOOST_DESCRIBE_CLASS (
469 (utils::UuidIdentifiableObject<ProcessorParameter>),
476 modulation_input_uuid_,
502class ProcessorParameterRegistry
504 OwningObjectRegistry<ProcessorParameterPtrVariant, ProcessorParameter>
507 ProcessorParameterRegistry (
508 dsp::PortRegistry &port_registry,
509 QObject * parent =
nullptr)
511 ProcessorParameterPtrVariant,
513 port_registry_ (port_registry)
520 const auto &map = get_hash_map ();
521 for (
const auto &kv : map)
523 if (std::get<ProcessorParameter *> (kv.second)->get_unique_id () ==
id)
525 return std::get<ProcessorParameter *> (kv.second);
534 auto * val = find_by_unique_id (
id);
535 if (val ==
nullptr) [[unlikely]]
537 throw std::runtime_error (
538 fmt::format (
"Processor Parameter with unique id {} not found",
id));
544 struct ProcessorParameterRegistryBuilder
546 ProcessorParameterRegistryBuilder (dsp::PortRegistry &port_registry)
547 : port_registry_ (port_registry)
551 template <
typename T> std::unique_ptr<T> build ()
const
553 return std::make_unique<T> (
558 dsp::PortRegistry &port_registry_;
562 from_json (
const nlohmann::json &j, ProcessorParameterRegistry ®)
564 from_json_with_builder (
565 j, reg, ProcessorParameterRegistryBuilder{ reg.port_registry_ });
569 dsp::PortRegistry &port_registry_;