21class ArrangerObjectFactory :
public QObject
26 using ArrangerObjectRegistry = structure::arrangement::ArrangerObjectRegistry;
27 using TrackResolver = structure::tracks::TrackResolver;
28 using ArrangerObjectSelectionManager =
29 structure::arrangement::ArrangerObjectSelectionManager;
39 using ArrangerObject = structure::arrangement ::ArrangerObject;
44 ArrangerObjectFactory () =
delete;
45 ArrangerObjectFactory (
46 ArrangerObjectRegistry ®istry,
47 TrackResolver track_resolver,
52 AudioClipResolverFunc clip_resolver,
53 RegisterNewAudioClipFunc clip_registration_func,
55 std::function<
bpm_t ()> bpm_provider,
56 ArrangerObjectSelectionManager timeline_selections_manager,
57 ArrangerObjectSelectionManager midi_selections_manager,
58 ArrangerObjectSelectionManager chord_selections_manager,
59 ArrangerObjectSelectionManager automation_selections_manager,
60 QObject * parent =
nullptr)
61 : QObject (parent), object_registry_ (registry),
62 track_resolver_ (std::move (track_resolver)),
63 settings_manager_ (settings_mgr),
64 frames_per_tick_getter_ (std::move (frames_per_tick_getter)),
65 snap_grid_timeline_ (snap_grid_timeline),
66 snap_grid_editor_ (snap_grid_editor),
67 clip_resolver_func_ (std::move (clip_resolver)),
68 new_clip_registration_func_ (std::move (clip_registration_func)),
69 sample_rate_provider_ (std::move (sample_rate_provider)),
70 bpm_provider_ (std::move (bpm_provider)),
71 timeline_selections_manager_ (timeline_selections_manager),
72 midi_selections_manager_ (midi_selections_manager),
73 chord_selections_manager_ (chord_selections_manager),
74 automation_selections_manager_ (automation_selections_manager)
78 static ArrangerObjectFactory * get_instance ();
80 template <structure::arrangement::FinalArrangerObjectSub
class ObjT>
83 friend class ArrangerObjectFactory;
87 ArrangerObjectRegistry ®istry,
88 TrackResolver track_resolver)
89 : registry_ (registry), track_resolver_ (std::move (track_resolver))
95 settings_manager_ = settings_manager;
101 frames_per_tick_ = framesPerTick;
105 Builder &with_clip_resolver (
const AudioClipResolverFunc &clip_resolver)
107 clip_resolver_ = clip_resolver;
111 Builder &with_clip (
const AudioClip::Uuid clip_id)
112 requires (std::is_same_v<ObjT, AudioRegion>)
114 clip_id_.emplace (clip_id);
119 Builder &with_start_ticks (
double start_ticks)
121 assert (settings_manager_.has_value ());
122 assert (frames_per_tick_.has_value ());
123 start_ticks_ = start_ticks;
128 Builder &with_end_ticks (
double end_ticks)
129 requires (std::derived_from<ObjT, structure::arrangement::BoundedObject>)
131 assert (frames_per_tick_.has_value ());
132 end_ticks_ = end_ticks;
138 structure::arrangement::NamedObject::NameValidator validator =
140 requires (std::derived_from<ObjT, structure::arrangement::NamedObject>)
143 name_validator_ = validator;
147 Builder &with_pitch (
const int pitch)
148 requires (std::is_same_v<ObjT, MidiNote>)
154 Builder &with_velocity (
const int vel)
155 requires (std::is_same_v<ObjT, MidiNote>)
161 Builder &with_automatable_value (
const double automatable_val)
162 requires (std::is_same_v<ObjT, AutomationPoint>)
164 automatable_value_ = automatable_val;
168 Builder &with_chord_descriptor (
const int chord_descriptor_index)
169 requires (std::is_same_v<ObjT, ChordObject>)
171 chord_descriptor_index_ = chord_descriptor_index;
176 requires (std::is_same_v<ObjT, ScaleObject>)
187 std::unique_ptr<ObjT> ret;
188 if constexpr (std::is_same_v<ObjT, AudioRegion>)
190 ret = std::make_unique<ObjT> (
191 registry_, track_resolver_, *clip_resolver_);
193 else if constexpr (std::is_same_v<ObjT, Marker>)
195 ret = std::make_unique<ObjT> (
196 registry_, track_resolver_, *name_validator_);
200 ret = std::make_unique<ObjT> (registry_, track_resolver_);
205 auto build_in_registry ()
207 auto obj_ref = [&] () {
210 structure::arrangement::ArrangerObjectUuidReference ret_ref{
211 obj_unique_ptr->get_uuid (), registry_
213 obj_unique_ptr.release ();
217 auto * obj = std::get<ObjT *> (obj_ref.get_object ());
220 if constexpr (std::is_same_v<ObjT, AudioRegion>)
222 obj->set_clip_id (*clip_id_);
223 obj->set_end_pos_full_size (
225 obj->get_position ().frames_
226 + clip_resolver_.value () (*clip_id_)->get_num_frames (),
227 to_ticks_per_frame (*frames_per_tick_) },
235 std::derived_from<ObjT, structure::arrangement::BoundedObject>)
237 obj->set_end_pos_full_size (
238 dsp::Position (*end_ticks_, *frames_per_tick_),
247 if (!end_ticks_ && !clip_id_)
250 std::derived_from<ObjT, structure::arrangement::BoundedObject>)
255 ObjT, structure::arrangement::TimelineObject>)
259 ->get_timelineLastCreatedObjectLengthInTicks ();
265 ->get_editorLastCreatedObjectLengthInTicks ();
267 obj->set_end_pos_full_size (
268 dsp::Position (*start_ticks_ + len_ticks, *frames_per_tick_),
272 obj->position_setter_validated (
273 dsp::Position (*start_ticks_, *frames_per_tick_),
274 to_ticks_per_frame (*frames_per_tick_));
280 std::derived_from<ObjT, structure::arrangement::NamedObject>)
282 obj->set_name (utils::Utf8String::from_qstring (*name_));
288 if constexpr (std::is_same_v<ObjT, MidiNote>)
290 obj->setPitch (*pitch_);
296 if constexpr (std::is_same_v<ObjT, MidiNote>)
298 obj->set_velocity (*velocity_);
302 if (automatable_value_)
304 if constexpr (std::is_same_v<ObjT, AutomationPoint>)
306 obj->setValue (*automatable_value_);
312 if constexpr (std::is_same_v<ObjT, ScaleObject>)
314 obj->set_scale (*scale_);
318 if constexpr (std::is_same_v<ObjT, AutomationPoint>)
322 gui::SettingsManager::automationCurveAlgorithm ());
325 if (chord_descriptor_index_)
327 if constexpr (std::is_same_v<ObjT, ChordObject>)
329 obj->set_chord_descriptor (*chord_descriptor_index_);
337 ArrangerObjectRegistry ®istry_;
338 TrackResolver track_resolver_;
339 OptionalRef<gui::SettingsManager> settings_manager_;
340 std::optional<dsp::FramesPerTick> frames_per_tick_;
341 std::optional<AudioClipResolverFunc> clip_resolver_;
342 std::optional<AudioClip::Uuid> clip_id_;
343 std::optional<double> start_ticks_;
344 std::optional<double> end_ticks_;
345 std::optional<QString> name_;
346 std::optional<structure::arrangement::NamedObject::NameValidator>
348 std::optional<int> pitch_;
349 std::optional<double> automatable_value_;
350 std::optional<int> chord_descriptor_index_;
351 std::optional<dsp::MusicalScale> scale_;
352 std::optional<int> velocity_;
355 template <
typename ObjT>
auto get_builder ()
const
359 .with_frames_per_tick (frames_per_tick_getter_ ())
360 .with_clip_resolver (clip_resolver_func_)
361 .with_settings_manager (settings_manager_);
369 template <structure::tracks::TrackLaneSub
class TrackLaneT>
370 void add_laned_object (TrackLaneT &lane,
auto obj_ref)
372 using RegionT =
typename TrackLaneT::RegionT;
377 typename base_type<
decltype (track)>::TrackLaneType, TrackLaneT>)
379 track->template add_region<RegionT> (
380 obj_ref,
nullptr, lane.get_index_in_track (),
true);
383 convert_to_variant<structure::tracks::LanedTrackPtrVariant> (
385 auto * obj = std::get<RegionT *> (obj_ref.get_object ());
386 timeline_selections_manager_.append_to_selection (obj->get_uuid ());
387 set_selection_handler_to_object (*obj);
393 auto create_audio_region_with_clip (
395 const AudioClip::Uuid &clip_id,
396 double startTicks)
const
399 get_builder<AudioRegion> ()
400 .with_start_ticks (startTicks)
402 .build_in_registry ();
412 auto create_audio_region_from_audio_buffer (
414 const utils::audio::AudioBuffer &buf,
415 utils::audio::BitDepth bit_depth,
416 const utils::Utf8String &clip_name,
417 double start_ticks)
const
419 auto clip = std::make_shared<AudioClip> (
420 buf, bit_depth, sample_rate_provider_ (), bpm_provider_ (), clip_name);
421 new_clip_registration_func_ (clip);
423 create_audio_region_with_clip (lane, clip->get_uuid (), start_ticks);
435 template <structure::arrangement::RegionWithChildren RegionT>
436 auto add_editor_object (
439 std::variant<int, double> value) -> RegionT::ChildT *
441 using ChildT =
typename RegionT::ChildT;
442 auto builder = get_builder<ChildT> ().with_start_ticks (startTicks);
443 if constexpr (std::is_same_v<ChildT, MidiNote>)
445 const auto ival = std::get<int> (value);
446 assert (ival >= 0 && ival < 128);
447 builder.with_pitch (ival);
449 else if constexpr (std::is_same_v<ChildT, AutomationPoint>)
451 builder.with_automatable_value (std::get<double> (value));
453 else if constexpr (std::is_same_v<ChildT, ChordObject>)
455 builder.with_chord_descriptor (std::get<int> (value));
457 auto obj_ref = builder.build_in_registry ();
458 region.add_object (obj_ref);
459 auto obj = std::get<ChildT *> (obj_ref.get_object ());
461 auto sel_mgr = get_selection_manager_for_object (*obj);
462 sel_mgr.append_to_selection (obj->get_uuid ());
463 set_selection_handler_to_object (*obj);
479 const AudioClip::Uuid &clip_id,
483 assert (clip_resolver_func_ (clip_id) !=
nullptr);
484 auto obj_ref = create_audio_region_with_clip (lane, clip_id, start_ticks);
485 add_laned_object (lane, obj_ref);
486 return std::get<AudioRegion *> (obj_ref.get_object ());
495 get_builder<ScaleObject> ()
496 .with_start_ticks (start_ticks)
498 .build_in_registry ();
499 chord_track.ArrangerObjectOwner<ScaleObject>::add_object (obj_ref);
500 return std::get<ScaleObject *> (obj_ref.get_object ());
503 Q_INVOKABLE Marker * addMarker (
510 get_builder<Marker> ()
511 .with_start_ticks (startTicks)
515 return markerTrack->validate_marker_name (inner_name);
517 .build_in_registry ();
518 markerTrack->add_object (marker_ref);
519 return std::get<Marker *> (marker_ref.get_object ());
522 Q_INVOKABLE MidiRegion *
526 get_builder<MidiRegion> ()
527 .with_start_ticks (startTicks)
528 .build_in_registry ();
529 add_laned_object (*lane, mr_ref);
530 return std::get<MidiRegion *> (mr_ref.get_object ());
533 Q_INVOKABLE ChordRegion *
534 addEmptyChordRegion (structure::tracks::ChordTrack * track,
double startTicks)
537 get_builder<ChordRegion> ()
538 .with_start_ticks (startTicks)
539 .build_in_registry ();
540 track->Track::add_region<ChordRegion> (cr_ref,
nullptr, std::nullopt,
true);
541 return std::get<ChordRegion *> (cr_ref.get_object ());
544 Q_INVOKABLE AutomationRegion * addEmptyAutomationRegion (
545 tracks::AutomationTrack * automationTrack,
550 get_builder<AutomationRegion> ()
551 .with_start_ticks (startTicks)
552 .build_in_registry ();
553 auto track_var = automationTrack->get_track ();
556 track->structure::tracks::Track::template add_region<AutomationRegion> (
557 ar_ref, automationTrack, std::nullopt,
true);
560 return std::get<AutomationRegion *> (ar_ref.get_object ());
563 AudioRegion * add_empty_audio_region_for_recording (
566 const utils::Utf8String &clip_name,
569 auto clip = std::make_shared<AudioClip> (
570 num_channels, 1, sample_rate_provider_ (), bpm_provider_ (), clip_name);
571 new_clip_registration_func_ (clip);
573 create_audio_region_with_clip (lane, clip->get_uuid (), start_ticks);
574 add_laned_object (lane, region_ref);
575 return std::get<AudioRegion *> (region_ref.get_object ());
578 Q_INVOKABLE AudioRegion * addAudioRegionFromFile (
580 const QString &absPath,
583 auto clip = std::make_shared<AudioClip> (
584 utils::Utf8String::from_qstring (absPath), sample_rate_provider_ (),
586 new_clip_registration_func_ (clip);
588 create_audio_region_with_clip (*lane, clip->get_uuid (), startTicks);
589 add_laned_object (*lane, ar_ref);
590 return std::get<AudioRegion *> (ar_ref.get_object ());
612 const QString &absolutePath,
616 Q_INVOKABLE MidiNote *
617 addMidiNote (MidiRegion * region,
double startTicks,
int pitch)
619 return add_editor_object (*region, startTicks, pitch);
623 addAutomationPoint (
AutomationRegion * region,
double startTicks,
double value)
626 return add_editor_object (*region, startTicks, value);
629 Q_INVOKABLE ChordObject *
630 addChordObject (ChordRegion * region,
double startTicks,
const int chordIndex)
633 return add_editor_object (*region, startTicks, chordIndex);
645 utils::audio::BitDepth bit_depth,
647 double start_ticks)
const
649 return create_audio_region_from_audio_buffer (
650 lane, buf, bit_depth, clip_name, start_ticks);
653 template <structure::arrangement::FinalArrangerObjectSub
class ObjT>
654 auto clone_new_object_identity (
const ObjT &other)
const
656 if constexpr (std::is_same_v<ObjT, AudioRegion>)
658 return object_registry_.clone_object (
659 other, object_registry_, track_resolver_, clip_resolver_func_);
663 return object_registry_.clone_object (
664 other, object_registry_, track_resolver_);
668 template <structure::arrangement::FinalArrangerObjectSub
class ObjT>
669 auto clone_object_snapshot (
const ObjT &other, QObject &owner)
const
672 if constexpr (std::is_same_v<ObjT, AudioRegion>)
675 new_obj = utils::clone_qobject (
677 track_resolver_, clip_resolver_func_);
679 else if constexpr (std::is_same_v<ObjT, Marker>)
681 new_obj = utils::clone_qobject (
683 track_resolver_, [] (
const auto &name) {
return true; });
687 new_obj = utils::clone_qobject (
694 template <structure::arrangement::FinalArrangerObjectSub
class ObjT>
695 auto get_selection_manager_for_object (
const ObjT &obj)
const
698 std::derived_from<ObjT, structure::arrangement::TimelineObject>)
700 return timeline_selections_manager_;
702 else if constexpr (std::is_same_v<ObjT, MidiNote>)
704 return midi_selections_manager_;
706 else if constexpr (std::is_same_v<ObjT, AutomationPoint>)
708 return automation_selections_manager_;
710 else if constexpr (std::is_same_v<ObjT, ChordObject>)
712 return chord_selections_manager_;
716 static_assert (
false);
720 template <structure::arrangement::FinalArrangerObjectSub
class ObjT>
721 void set_selection_handler_to_object (ObjT &obj)
723 auto sel_mgr = get_selection_manager_for_object (obj);
724 obj.set_selection_status_getter ([sel_mgr] (
const ArrangerObject::Uuid &
id) {
725 return sel_mgr.is_selected (
id);
730 ArrangerObjectRegistry &object_registry_;
731 TrackResolver track_resolver_;
732 gui::SettingsManager &settings_manager_;
733 std::function<dsp::FramesPerTick ()> frames_per_tick_getter_;
734 gui::SnapGrid &snap_grid_timeline_;
735 gui::SnapGrid &snap_grid_editor_;
736 AudioClipResolverFunc clip_resolver_func_;
737 RegisterNewAudioClipFunc new_clip_registration_func_;
739 std::function<
bpm_t ()> bpm_provider_;
740 ArrangerObjectSelectionManager timeline_selections_manager_;
741 ArrangerObjectSelectionManager midi_selections_manager_;
742 ArrangerObjectSelectionManager chord_selections_manager_;
743 ArrangerObjectSelectionManager automation_selections_manager_;