21 using MusicalModeGetter = std::function<bool ()>;
22 using LastTimelineObjectLengthProvider = std::function<double ()>;
23 using LastEditorObjectLengthProvider = std::function<double ()>;
24 using AutomationCurveAlgorithmProvider =
27 const dsp::TempoMap &tempo_map_;
28 ArrangerObjectRegistry &object_registry_;
29 dsp::FileAudioSourceRegistry &file_audio_source_registry_;
30 MusicalModeGetter musical_mode_getter_;
31 LastTimelineObjectLengthProvider last_timeline_obj_len_provider_;
32 LastEditorObjectLengthProvider last_editor_obj_len_provider_;
33 AutomationCurveAlgorithmProvider automation_curve_algorithm_provider_;
49 friend class ArrangerObjectFactory;
53 : dependencies_ (std::move (dependencies))
57 Builder &with_clip (dsp::FileAudioSourceUuidReference clip_id)
58 requires (std::is_same_v<ObjT, AudioRegion>)
60 clip_id_.emplace (std::move (clip_id));
65 Builder &with_start_ticks (
double start_ticks)
67 start_ticks_ = start_ticks;
72 Builder &with_end_ticks (
double end_ticks)
75 end_ticks_ = end_ticks;
79 Builder &with_name (
const QString &name)
86 Builder &with_pitch (
const int pitch)
87 requires (std::is_same_v<ObjT, MidiNote>)
93 Builder &with_velocity (
const int vel)
94 requires (std::is_same_v<ObjT, MidiNote>)
100 Builder &with_automatable_value (
const double automatable_val)
101 requires (std::is_same_v<ObjT, AutomationPoint>)
103 automatable_value_ = automatable_val;
107 Builder &with_chord_descriptor (
const int chord_descriptor_index)
108 requires (std::is_same_v<ObjT, ChordObject>)
110 chord_descriptor_index_ = chord_descriptor_index;
115 requires (std::is_same_v<ObjT, ScaleObject>)
117 scale_ = std::move (scale);
122 requires (std::is_same_v<ObjT, Marker>)
124 marker_type_ = marker_type;
133 std::unique_ptr<ObjT> ret;
134 if constexpr (std::is_same_v<ObjT, AudioRegion>)
136 ret = std::make_unique<ObjT> (
137 dependencies_.tempo_map_, dependencies_.object_registry_,
138 dependencies_.file_audio_source_registry_,
139 dependencies_.musical_mode_getter_);
143 ret = std::make_unique<ObjT> (
144 dependencies_.tempo_map_, dependencies_.object_registry_,
145 dependencies_.file_audio_source_registry_);
147 else if constexpr (std::is_same_v<ObjT, Marker>)
149 ret = std::make_unique<ObjT> (
150 dependencies_.tempo_map_,
153 else if constexpr (std::is_same_v<ObjT, AudioSourceObject>)
155 auto file_audio_source =
156 dependencies_.file_audio_source_registry_.create_object<
158 1, 1, units::sample_rate (44100), 120, u8
"dummy");
159 ret = std::make_unique<ObjT> (
160 dependencies_.tempo_map_, dependencies_.file_audio_source_registry_,
165 ret = std::make_unique<ObjT> (dependencies_.tempo_map_);
170 auto build_in_registry ()
172 auto obj_ref = [&] () {
174 dependencies_.object_registry_.register_object (obj_unique_ptr.get ());
175 structure::arrangement::ArrangerObjectUuidReference ret_ref{
176 obj_unique_ptr->get_uuid (), dependencies_.object_registry_
178 obj_unique_ptr.release ();
182 auto * obj = std::get<ObjT *> (obj_ref.get_object ());
184 if constexpr (RegionObject<ObjT>)
186 obj->loopRange ()->setTrackBounds (
true);
191 if (!end_ticks_ && !clip_id_)
193 if constexpr (BoundedObject<ObjT>)
196 if constexpr (TimelineObject<ObjT>)
199 dependencies_.last_timeline_obj_len_provider_ ();
203 len_ticks = dependencies_.last_editor_obj_len_provider_ ();
205 get_object_bounds (*obj)->length ()->setTicks (len_ticks);
208 obj->position ()->setTicks (*start_ticks_);
213 if constexpr (std::is_same_v<ObjT, AudioRegion>)
215 auto source_object = dependencies_.object_registry_.create_object<
217 dependencies_.tempo_map_,
218 dependencies_.file_audio_source_registry_, clip_id_.value ());
219 obj->set_source (source_object);
220 obj->bounds ()->length ()->setSamples (
222 .template get_object_as<dsp::FileAudioSource> ()
223 ->get_num_frames ());
229 if constexpr (BoundedObject<ObjT>)
231 get_object_bounds (*obj)->length ()->setTicks (
232 *end_ticks_ - obj->position ()->ticks ());
238 if constexpr (NamedObject<ObjT>)
240 if constexpr (RegionObject<ObjT>)
242 obj->name ()->setName (*name_);
246 obj->name ()->setName (*name_);
253 if constexpr (std::is_same_v<ObjT, MidiNote>)
255 obj->setPitch (*pitch_);
261 if constexpr (std::is_same_v<ObjT, MidiNote>)
263 obj->setVelocity (*velocity_);
267 if (automatable_value_)
269 if constexpr (std::is_same_v<ObjT, AutomationPoint>)
271 obj->setValue (
static_cast<float> (*automatable_value_));
277 if constexpr (std::is_same_v<ObjT, ScaleObject>)
279 obj->setScale (scale_.release ());
283 if constexpr (std::is_same_v<ObjT, AutomationPoint>)
285 obj->curveOpts ()->setAlgorithm (
286 dependencies_.automation_curve_algorithm_provider_ ());
289 if (chord_descriptor_index_)
291 if constexpr (std::is_same_v<ObjT, ChordObject>)
293 obj->setChordDescriptorIndex (*chord_descriptor_index_);
301 Dependencies dependencies_;
302 std::optional<dsp::FileAudioSourceUuidReference> clip_id_;
303 std::optional<double> start_ticks_;
304 std::optional<double> end_ticks_;
305 std::optional<QString> name_;
306 std::optional<int> pitch_;
307 std::optional<double> automatable_value_;
308 std::optional<int> chord_descriptor_index_;
309 utils::QObjectUniquePtr<dsp::MusicalScale> scale_;
310 std::optional<int> velocity_;
311 std::optional<Marker::MarkerType> marker_type_;
382 requires (!std::is_same_v<RegionT, structure::arrangement::AudioRegion>)
384 using ChildT =
typename RegionT::ArrangerObjectChildType;
386 std::move (get_builder<ChildT> ().with_start_ticks (startTicks));
387 if constexpr (std::is_same_v<ChildT, MidiNote>)
389 const auto ival = std::get<int> (value);
390 assert (ival >= 0 && ival < 128);
391 builder.with_pitch (ival);
393 else if constexpr (std::is_same_v<ChildT, AutomationPoint>)
395 builder.with_automatable_value (std::get<double> (value));
397 else if constexpr (std::is_same_v<ChildT, ChordObject>)
399 builder.with_chord_descriptor (std::get<int> (value));
401 return builder.build_in_registry ();