48 friend class ArrangerObjectFactory;
52 : dependencies_ (std::move (dependencies))
56 Builder &with_clip (dsp::FileAudioSourceUuidReference clip_id)
57 requires (std::is_same_v<ObjT, AudioClip>)
59 clip_id_.emplace (std::move (clip_id));
64 Builder &with_start_ticks (units::precise_tick_t start_ticks)
66 start_ticks_ = start_ticks;
71 Builder &with_end_ticks (units::precise_tick_t end_ticks)
74 end_ticks_ = end_ticks;
78 Builder &with_name (
const QString &name)
85 Builder &with_pitch (
const int pitch)
86 requires (std::is_same_v<ObjT, MidiNote>)
92 Builder &with_velocity (
const int vel)
93 requires (std::is_same_v<ObjT, MidiNote>)
99 Builder &with_midi_channel (
const int channel)
101 std::is_same_v<ObjT, MidiNote> || std::is_same_v<ObjT, MidiControlEvent>)
103 midi_channel_ = channel;
107 Builder &with_automatable_value (
const double automatable_val)
108 requires (std::is_same_v<ObjT, AutomationPoint>)
110 automatable_value_ = automatable_val;
114 Builder &with_chord_descriptor (
115 dsp::MusicalNote root,
117 dsp::ChordAccent accent = dsp::ChordAccent::None,
119 std::optional<dsp::MusicalNote> bass = std::nullopt)
120 requires (std::is_same_v<ObjT, ChordObject>)
122 chord_descr_ = utils::make_qobject_unique<dsp::ChordDescriptor> (
123 root, type, accent, inversion, bass);
128 requires (std::is_same_v<ObjT, ScaleObject>)
130 scale_ = std::move (scale);
135 requires (std::is_same_v<ObjT, Marker>)
137 marker_type_ = marker_type;
146 std::unique_ptr<ObjT> ret;
149 ret = std::make_unique<ObjT> (
150 dependencies_.tempo_map_, dependencies_.registry_);
152 else if constexpr (std::is_same_v<ObjT, Marker>)
154 ret = std::make_unique<ObjT> (
155 dependencies_.tempo_map_,
158 else if constexpr (std::is_same_v<ObjT, AudioSourceObject>)
162 auto file_audio_source = utils::create_object<dsp::FileAudioSource> (
163 dependencies_.registry_, dummy_buf,
164 utils::audio::BitDepth::BIT_DEPTH_32, units::sample_rate (44100),
165 units::bpm (120.0), u8
"dummy");
166 ret = std::make_unique<ObjT> (
167 dependencies_.tempo_map_, dependencies_.registry_,
172 ret = std::make_unique<ObjT> (dependencies_.tempo_map_);
177 auto build_in_registry ()
179 auto obj_ref = [&] () {
181 dependencies_.registry_.register_object (*obj_unique_ptr);
183 obj_unique_ptr->get_uuid (), dependencies_.registry_
185 obj_unique_ptr.release ();
189 auto * obj = obj_ref.template get_object_as<ObjT> ();
191 if constexpr (ClipObject<ObjT>)
193 obj->setTrackBounds (
true);
198 if (!end_ticks_ && !clip_id_)
200 if constexpr (BoundedObject<ObjT>)
203 if constexpr (TimelineObject<ObjT>)
206 dependencies_.last_timeline_obj_len_provider_ ();
210 len_ticks = dependencies_.last_editor_obj_len_provider_ ();
212 obj->length ()->setTicks (len_ticks);
215 obj->position ()->setTicks ((*start_ticks_).in (units::ticks));
220 if constexpr (std::is_same_v<ObjT, AudioClip>)
222 auto source_object = utils::create_object<AudioSourceObject> (
223 dependencies_.registry_, dependencies_.tempo_map_,
224 dependencies_.registry_, clip_id_.value ());
225 obj->set_source (source_object);
234 if constexpr (BoundedObject<ObjT>)
236 set_end_from_timeline_ticks (
237 *obj, dsp::TimelineTick{ *end_ticks_ });
243 if constexpr (NamedObject<ObjT>)
245 if constexpr (ClipObject<ObjT>)
247 obj->name ()->setName (*name_);
251 obj->name ()->setName (*name_);
258 if constexpr (std::is_same_v<ObjT, MidiNote>)
260 obj->setPitch (*pitch_);
266 if constexpr (std::is_same_v<ObjT, MidiNote>)
268 obj->setVelocity (*velocity_);
274 if constexpr (std::is_same_v<ObjT, MidiNote>)
276 obj->setMidiChannel (*midi_channel_);
278 else if constexpr (std::is_same_v<ObjT, MidiControlEvent>)
280 obj->setChannel (*midi_channel_);
284 if (automatable_value_)
286 if constexpr (std::is_same_v<ObjT, AutomationPoint>)
288 obj->setValue (
static_cast<float> (*automatable_value_));
294 if constexpr (std::is_same_v<ObjT, ScaleObject>)
296 obj->setScale (scale_.release ());
300 if constexpr (std::is_same_v<ObjT, AutomationPoint>)
302 obj->curveOpts ()->setAlgorithm (
303 dependencies_.automation_curve_algorithm_provider_ ());
308 if constexpr (std::is_same_v<ObjT, ChordObject>)
310 auto * dest = obj->chordDescriptor ();
311 dest->setRootNote (chord_descr_->rootNote ());
312 dest->setChordType (chord_descr_->chordType ());
313 dest->setChordAccent (chord_descr_->chordAccent ());
314 dest->setInversion (chord_descr_->inversion ());
315 if (chord_descr_->hasBass ())
316 dest->setBassNote (chord_descr_->bassNote ());
324 Dependencies dependencies_;
325 std::optional<dsp::FileAudioSourceUuidReference> clip_id_;
326 std::optional<units::precise_tick_t> start_ticks_;
327 std::optional<units::precise_tick_t> end_ticks_;
328 std::optional<QString> name_;
329 std::optional<int> pitch_;
330 std::optional<double> automatable_value_;
331 utils::QObjectUniquePtr<dsp::ChordDescriptor> chord_descr_;
332 utils::QObjectUniquePtr<dsp::MusicalScale> scale_;
333 std::optional<int> velocity_;
334 std::optional<int> midi_channel_;
335 std::optional<Marker::MarkerType> marker_type_;
396 units::precise_tick_t startTicks,
397 std::variant<int, double> value)
400 std::move (get_builder<ChildT> ().with_start_ticks (startTicks));
401 if constexpr (std::is_same_v<ChildT, MidiNote>)
403 const auto ival = std::get<int> (value);
404 assert (ival >= 0 && ival < 128);
405 builder.with_pitch (ival);
407 else if constexpr (std::is_same_v<ChildT, AutomationPoint>)
409 builder.with_automatable_value (std::get<double> (value));
411 else if constexpr (std::is_same_v<ChildT, ChordObject>)
415 const auto root =
static_cast<dsp::MusicalNote
> (std::get<int> (value));
416 builder.with_chord_descriptor (root, dsp::ChordType::Major);
418 return builder.build_in_registry ();