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>)
157 auto file_audio_source =
158 dependencies_.file_audio_source_registry_.create_object<
160 dummy_buf, utils::audio::BitDepth::BIT_DEPTH_32,
161 units::sample_rate (44100), 120, u8
"dummy");
162 ret = std::make_unique<ObjT> (
163 dependencies_.tempo_map_, dependencies_.file_audio_source_registry_,
168 ret = std::make_unique<ObjT> (dependencies_.tempo_map_);
173 auto build_in_registry ()
175 auto obj_ref = [&] () {
177 dependencies_.object_registry_.register_object (obj_unique_ptr.get ());
178 structure::arrangement::ArrangerObjectUuidReference ret_ref{
179 obj_unique_ptr->get_uuid (), dependencies_.object_registry_
181 obj_unique_ptr.release ();
185 auto * obj = std::get<ObjT *> (obj_ref.get_object ());
187 if constexpr (RegionObject<ObjT>)
189 obj->loopRange ()->setTrackBounds (
true);
194 if (!end_ticks_ && !clip_id_)
196 if constexpr (BoundedObject<ObjT>)
199 if constexpr (TimelineObject<ObjT>)
202 dependencies_.last_timeline_obj_len_provider_ ();
206 len_ticks = dependencies_.last_editor_obj_len_provider_ ();
208 get_object_bounds (*obj)->length ()->setTicks (len_ticks);
211 obj->position ()->setTicks (*start_ticks_);
216 if constexpr (std::is_same_v<ObjT, AudioRegion>)
218 auto source_object = dependencies_.object_registry_.create_object<
220 dependencies_.tempo_map_,
221 dependencies_.file_audio_source_registry_, clip_id_.value ());
222 obj->set_source (source_object);
223 obj->bounds ()->length ()->setSamples (
225 .template get_object_as<dsp::FileAudioSource> ()
226 ->get_num_frames ());
232 if constexpr (BoundedObject<ObjT>)
234 get_object_bounds (*obj)->length ()->setTicks (
235 *end_ticks_ - obj->position ()->ticks ());
241 if constexpr (NamedObject<ObjT>)
243 if constexpr (RegionObject<ObjT>)
245 obj->name ()->setName (*name_);
249 obj->name ()->setName (*name_);
256 if constexpr (std::is_same_v<ObjT, MidiNote>)
258 obj->setPitch (*pitch_);
264 if constexpr (std::is_same_v<ObjT, MidiNote>)
266 obj->setVelocity (*velocity_);
270 if (automatable_value_)
272 if constexpr (std::is_same_v<ObjT, AutomationPoint>)
274 obj->setValue (
static_cast<float> (*automatable_value_));
280 if constexpr (std::is_same_v<ObjT, ScaleObject>)
282 obj->setScale (scale_.release ());
286 if constexpr (std::is_same_v<ObjT, AutomationPoint>)
288 obj->curveOpts ()->setAlgorithm (
289 dependencies_.automation_curve_algorithm_provider_ ());
292 if (chord_descriptor_index_)
294 if constexpr (std::is_same_v<ObjT, ChordObject>)
296 obj->setChordDescriptorIndex (*chord_descriptor_index_);
304 Dependencies dependencies_;
305 std::optional<dsp::FileAudioSourceUuidReference> clip_id_;
306 std::optional<double> start_ticks_;
307 std::optional<double> end_ticks_;
308 std::optional<QString> name_;
309 std::optional<int> pitch_;
310 std::optional<double> automatable_value_;
311 std::optional<int> chord_descriptor_index_;
312 utils::QObjectUniquePtr<dsp::MusicalScale> scale_;
313 std::optional<int> velocity_;
314 std::optional<Marker::MarkerType> marker_type_;
374 requires (!std::is_same_v<RegionT, structure::arrangement::AudioRegion>)
376 using ChildT =
typename RegionT::ArrangerObjectChildType;
378 std::move (get_builder<ChildT> ().with_start_ticks (startTicks));
379 if constexpr (std::is_same_v<ChildT, MidiNote>)
381 const auto ival = std::get<int> (value);
382 assert (ival >= 0 && ival < 128);
383 builder.with_pitch (ival);
385 else if constexpr (std::is_same_v<ChildT, AutomationPoint>)
387 builder.with_automatable_value (std::get<double> (value));
389 else if constexpr (std::is_same_v<ChildT, ChordObject>)
391 builder.with_chord_descriptor (std::get<int> (value));
393 return builder.build_in_registry ();