2 #include <Process/Dataflow/WidgetInlets.hpp>
3 #include <Process/ProcessFlags.hpp>
4 #include <Process/ProcessMetadata.hpp>
6 #include <Dataflow/CurveInlet.hpp>
8 #include <score/plugins/UuidKey.hpp>
10 #include <ossia/dataflow/audio_port.hpp>
11 #include <ossia/dataflow/port.hpp>
12 #include <ossia/dataflow/safe_nodes/tick_policies.hpp>
13 #include <ossia/detail/span.hpp>
15 #include <boost/container/vector.hpp>
17 #include <avnd/binding/ossia/qt.hpp>
18 #include <avnd/common/concepts_polyfill.hpp>
19 #include <avnd/common/struct_reflection.hpp>
20 #include <avnd/concepts/audio_port.hpp>
21 #include <avnd/concepts/channels.hpp>
22 #include <avnd/concepts/curve.hpp>
23 #include <avnd/concepts/gfx.hpp>
24 #include <avnd/concepts/midi_port.hpp>
25 #include <avnd/concepts/parameter.hpp>
26 #include <avnd/wrappers/metadatas.hpp>
27 #include <avnd/wrappers/widgets.hpp>
31 #include <type_traits>
33 #define make_uuid(text) score::uuids::string_generator::compute((text))
35 #define uuid_constexpr inline
37 #define uuid_constexpr constexpr
42 template <
typename Node,
typename FieldIndex>
43 struct CustomFloatControl;
46 template <
typename Node,
typename FieldIndex>
47 struct is_custom_serialized<oscr::CustomFloatControl<Node, FieldIndex>> : std::true_type
56 if constexpr(requires {
59 } -> std::convertible_to<score::uuid_t>;
66 constexpr
const char* str = N::uuid();
67 return score::uuids::string_generator::compute(str, str + 37);
71 template <
typename Node>
77 memcpy(dat, node_uuid.data, 16);
82 memcpy(node_uuid.data, dat, 16);
89 using Process::ControlInlet::ControlInlet;
98 setDomain(ossia::make_domain(min, max));
102 auto getMin()
const noexcept {
return domain().get().template convert_min<float>(); }
103 auto getMax()
const noexcept {
return domain().get().template convert_max<float>(); }
105 void setupExecution(ossia::inlet& inl)
const noexcept
override
107 auto& port = **safe_cast<ossia::value_inlet*>(&inl);
108 port.type = ossia::val_type::FLOAT;
109 port.domain = domain().get();
113 template <
typename Node,
typename FieldIndex>
116 using CustomFloatControlBase::CustomFloatControlBase;
118 static key_type static_concreteKey() noexcept
120 return make_field_uuid<Node>(
true, FieldIndex{});
122 key_type concreteKey()
const noexcept
override {
return static_concreteKey(); }
124 void serialize_impl(
const VisitorVariant& vis)
const noexcept
override
126 score::serialize_dyn(vis, *
this);
133 template <
typename Node,
typename FieldIndex>
145 template <
typename Node,
typename FieldIndex>
160 template <
typename Node,
typename T, std::
size_t N>
161 auto make_control_in(avnd::field_index<N>,
Id<Process::Port>&&
id, QObject* parent)
163 using value_type = as_type(T::value);
164 constexpr
auto name = avnd::get_name<T>();
165 QString qname = QString::fromUtf8(name.data(), name.size());
167 constexpr
auto widg = avnd::get_widget<T>();
171 if constexpr(avnd::curve_port<T>)
175 else if constexpr(widg.widget == avnd::widget_type::bang)
177 return new Process::ImpulseButton{qname, id, parent};
179 else if constexpr(widg.widget == avnd::widget_type::button)
181 return new Process::Button{qname, id, parent};
183 else if constexpr(widg.widget == avnd::widget_type::toggle)
185 constexpr
auto c = avnd::get_range<T>();
186 if constexpr(requires { c.values(); })
188 return new Process::ChooserToggle{
189 {c.values[0], c.values[1]}, c.init, qname, id, parent};
193 return new Process::Toggle{bool(c.init), qname, id, parent};
196 else if constexpr(widg.widget == avnd::widget_type::slider)
198 constexpr
auto c = avnd::get_range<T>();
199 if constexpr(std::is_integral_v<value_type>)
201 return new Process::IntSlider{c.min, c.max, c.init, qname, id, parent};
205 if constexpr(avnd::has_mapper<T>)
207 return new CustomFloatControl<Node, avnd::field_index<N>>{c.min, c.max, c.init,
212 return new Process::FloatSlider{c.min, c.max, c.init, qname, id, parent};
216 else if constexpr(widg.widget == avnd::widget_type::time_chooser)
218 constexpr
auto c = avnd::get_range<T>();
219 return new Process::TimeChooser{c.min, c.max, c.init, qname, id, parent};
221 else if constexpr(widg.widget == avnd::widget_type::range_slider)
223 constexpr
auto c = avnd::get_range<T>();
224 if constexpr(std::is_integral_v<value_type>)
226 auto [start, end] = c.init;
227 return new Process::IntRangeSlider{c.min, c.max, {(float)start, (
float)end},
232 auto [start, end] = c.init;
233 return new Process::FloatRangeSlider{c.min, c.max, {(float)start, (
float)end},
237 else if constexpr(widg.widget == avnd::widget_type::range_spinbox)
239 constexpr
auto c = avnd::get_range<T>();
240 if constexpr(std::is_integral_v<value_type>)
242 auto [start, end] = c.init;
243 return new Process::IntRangeSpinBox{c.min, c.max, {(float)start, (
float)end},
248 auto [start, end] = c.init;
249 return new Process::FloatRangeSpinBox{c.min, c.max, {(float)start, (
float)end},
253 else if constexpr(widg.widget == avnd::widget_type::spinbox)
255 constexpr
auto c = avnd::get_range<T>();
256 if constexpr(std::is_integral_v<value_type>)
258 return new Process::IntSpinBox{c.min, c.max, c.init, qname, id, parent};
262 return new Process::FloatSpinBox{c.min, c.max, c.init, qname, id, parent};
265 else if constexpr(widg.widget == avnd::widget_type::knob)
267 constexpr
auto c = avnd::get_range<T>();
268 if constexpr(std::is_integral_v<value_type>)
271 return new Process::IntSlider{c.min, c.max, c.init, qname, id, parent};
275 if constexpr(avnd::has_mapper<T>)
277 return new CustomFloatControl<Node, avnd::field_index<N>>{c.min, c.max, c.init,
282 return new Process::FloatKnob{c.min, c.max, c.init, qname, id, parent};
286 else if constexpr(widg.widget == avnd::widget_type::lineedit)
288 if constexpr(avnd::has_range<T>)
290 constexpr
auto c = avnd::get_range<T>();
291 if constexpr(avnd::program_parameter<T>)
293 auto p =
new Process::ProgramEdit{c.init.data(), qname, id, parent};
294 p->language = T::language();
298 return new Process::LineEdit{c.init.data(), qname, id, parent};
302 if constexpr(avnd::program_parameter<T>)
304 auto p =
new Process::ProgramEdit{
"", qname, id, parent};
305 p->language = T::language();
309 return new Process::LineEdit{
"", qname, id, parent};
312 else if constexpr(widg.widget == avnd::widget_type::combobox)
314 constexpr
auto c = avnd::get_range<T>();
315 return new Process::ComboBox{to_combobox_range(c.values), c.init, qname, id, parent};
317 else if constexpr(widg.widget == avnd::widget_type::choices)
319 constexpr
auto c = avnd::get_range<T>();
320 auto enums = avnd::to_enum_range(c.values);
321 auto init = enums[c.init];
322 std::vector<QString> pixmaps;
323 if constexpr(requires { c.pixmaps; })
325 for(
auto& pix : c.pixmaps)
327 pixmaps.push_back(QString::fromLatin1(pix.data(), pix.size()));
330 return new Process::Enum{
331 std::move(enums), pixmaps, std::move(init), qname, id, parent};
333 else if constexpr(widg.widget == avnd::widget_type::xy)
335 constexpr
auto c = avnd::get_range<T>();
336 if constexpr(requires {
342 return new Process::XYSlider{
343 {c.min, c.min}, {c.max, c.max}, {c.init, c.init}, qname, id, parent};
347 auto [mx, my] = c.min;
348 auto [Mx, My] = c.max;
349 auto [ix, iy] = c.init;
350 return new Process::XYSlider{{mx, my}, {Mx, My}, {ix, iy}, qname, id, parent};
353 else if constexpr(widg.widget == avnd::widget_type::xyz)
355 constexpr
auto c = avnd::get_range<T>();
356 if constexpr(requires {
362 return new Process::XYZSlider{
363 {c.min, c.min, c.min},
364 {c.max, c.max, c.max},
365 {c.init, c.init, c.init},
372 auto [mx, my, mz] = c.min;
373 auto [Mx, My, Mz] = c.max;
374 auto [ix, iy, iz] = c.init;
375 return new Process::XYZSlider{{mx, my, mz}, {Mx, My, Mz}, {ix, iy, iz},
379 else if constexpr(widg.widget == avnd::widget_type::xy_spinbox)
381 using data_type = std::decay_t<decltype(value_type{}.x)>;
382 constexpr
auto c = avnd::get_range<T>();
383 if constexpr(requires {
389 return new Process::XYSpinboxes{
393 std::is_integral_v<data_type>,
400 auto [mx, my] = c.min;
401 auto [Mx, My] = c.max;
402 auto [ix, iy] = c.init;
403 return new Process::XYSpinboxes{
404 {mx, my}, {Mx, My}, {ix, iy}, std::is_integral_v<data_type>,
408 else if constexpr(widg.widget == avnd::widget_type::xyz_spinbox)
410 constexpr
auto c = avnd::get_range<T>();
411 if constexpr(requires {
417 return new Process::XYZSpinboxes{
418 {c.min, c.min, c.min},
419 {c.max, c.max, c.max},
420 {c.init, c.init, c.init},
427 auto [mx, my, mz] = c.min;
428 auto [Mx, My, Mz] = c.max;
429 auto [ix, iy, iz] = c.init;
430 return new Process::XYZSpinboxes{{mx, my, mz}, {Mx, My, Mz}, {ix, iy, iz},
434 else if constexpr(widg.widget == avnd::widget_type::color)
436 constexpr
auto c = avnd::get_range<T>();
437 constexpr
auto i = c.init;
438 return new Process::HSVSlider{{i.r, i.g, i.b, i.a}, qname, id, parent};
442 static_assert(T::is_not_a_valid_control);
446 template <
typename T, std::
size_t N>
447 auto make_control_out(avnd::field_index<N>,
Id<Process::Port>&&
id, QObject* parent)
449 constexpr
auto name = avnd::get_name<T>();
450 constexpr
auto widg = avnd::get_widget<T>();
451 QString qname = QString::fromUtf8(name.data(), name.size());
455 if constexpr(widg.widget == avnd::widget_type::bargraph)
457 constexpr
auto c = avnd::get_range<T>();
458 return new Process::Bargraph{c.min, c.max, c.init, qname, id, parent};
460 else if constexpr(avnd::fp_ish<decltype(T::value)>)
462 constexpr
auto c = avnd::get_range<T>();
463 return new Process::Bargraph{c.min, c.max, c.init, qname, id, parent};
467 static_assert(T::is_not_a_valid_control);
471 template <
typename T>
472 constexpr
auto make_control_out(
const T& t)
474 return make_control_out<T>();
482 ossia::audio_vector* buffer{};
486 tcb::span<const double> operator[](std::size_t i)
const noexcept
488 auto& chan = (*buffer)[i];
489 int64_t min_dur = std::min(int64_t(chan.size()) - offset, duration);
493 return tcb::span<const double>{chan.data() + offset, std::size_t(min_dur)};
496 std::size_t channels()
const noexcept {
return buffer->size(); }
497 void resize(std::size_t i)
const noexcept {
return buffer->resize(i); }
498 void reserve(std::size_t channels, std::size_t bufferSize)
501 for(
auto& vec : *buffer)
502 vec.reserve(bufferSize);
508 ossia::audio_vector* buffer{};
512 tcb::span<double> operator[](std::size_t i)
const noexcept
514 auto& chan = (*buffer)[i];
515 int64_t min_dur = std::min(int64_t(chan.size()) - offset, duration);
519 return tcb::span<double>{chan.data() + offset, std::size_t(min_dur)};
522 std::size_t channels()
const noexcept {
return buffer->size(); }
523 void resize(std::size_t channels, std::size_t samples_to_write)
const noexcept
525 buffer->resize(channels);
526 for(
auto& c : *buffer)
527 c.resize(offset + samples_to_write);
530 void reserve(std::size_t channels, std::size_t bufferSize)
532 buffer->resize(channels);
533 for(
auto& c : *buffer)
534 c.reserve(bufferSize);
Definition: QmlObjects.hpp:109
Definition: VisitorInterface.hpp:53
Definition: DataStreamVisitor.hpp:27
Definition: DataStreamVisitor.hpp:202
Definition: VisitorInterface.hpp:61
Definition: JSONVisitor.hpp:52
Definition: JSONVisitor.hpp:423
Definition: score-lib-process/Process/Dataflow/Port.hpp:202
Definition: UuidKey.hpp:343
The id_base_t class.
Definition: Identifier.hpp:57
Definition: CurveInlet.hpp:47
Definition: VisitorInterface.hpp:13
The VisitorVariant struct.
Definition: VisitorInterface.hpp:26
Definition: Concepts.hpp:88
Definition: Concepts.hpp:115
Definition: Concepts.hpp:481
Definition: Concepts.hpp:507
Definition: UuidKey.hpp:24