Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
arranger_object_creator.h
1// SPDX-FileCopyrightText: © 2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include <utility>
7
8#include "commands/add_arranger_object_command.h"
9#include "dsp/snap_grid.h"
10#include "structure/arrangement/arranger_object_all.h"
11#include "structure/arrangement/arranger_object_factory.h"
12#include "structure/arrangement/arranger_object_owner.h"
13#include "structure/arrangement/tempo_object_manager.h"
14#include "structure/scenes/clip_slot.h"
15#include "structure/tracks/track_all.h"
16#include "undo/undo_stack.h"
17
18namespace zrythm::actions
19{
20class ArrangerObjectCreator : public QObject
21{
22 Q_OBJECT
23 QML_ELEMENT
24 QML_UNCREATABLE ("One instance per project")
25
26public:
27 explicit ArrangerObjectCreator (
28 undo::UndoStack &undo_stack,
29 structure::arrangement::ArrangerObjectFactory &arranger_object_factory,
30 dsp::SnapGrid &snap_grid_timeline,
31 dsp::SnapGrid &snap_grid_editor,
32 QObject * parent = nullptr)
33 : QObject (parent), arranger_object_factory_ (arranger_object_factory),
34 snap_grid_timeline_ (snap_grid_timeline),
35 snap_grid_editor_ (snap_grid_editor), undo_stack_ (undo_stack)
36 {
37 }
38
39 Q_INVOKABLE structure::arrangement::Marker * addMarker (
42 const QString &name,
43 double startTicks);
44
45 Q_INVOKABLE structure::arrangement::TempoObject * addTempoObject (
47 double bpm,
48 structure::arrangement::TempoObject::CurveType curveType,
49 double startTicks);
50
52 addTimeSignatureObject (
54 int numerator,
55 int denominator,
56 double startTicks);
57
58 Q_INVOKABLE structure::arrangement::MidiRegion * addEmptyMidiRegion (
61 double startTicks);
62
63 Q_INVOKABLE structure::arrangement::MidiRegion * addEmptyMidiRegionToClip (
66 {
67 auto mr_ref =
68 arranger_object_factory_
70 .with_start_ticks (0)
71 .build_in_registry ();
72 clipSlot->setRegion (
73 mr_ref.get_object_as<structure::arrangement::MidiRegion> ());
74 return mr_ref.get_object_as<structure::arrangement::MidiRegion> ();
75 }
76
78 addEmptyChordRegion (structure::tracks::ChordTrack * track, double startTicks);
79
81 addEmptyAutomationRegion (
83 structure::tracks::AutomationTrack * automationTrack,
84 double startTicks);
85
97 dsp::FileAudioSourceUuidReference clip_id,
98 double start_ticks)
99 {
100 auto obj_ref = arranger_object_factory_.create_audio_region_with_clip (
101 std::move (clip_id), start_ticks);
102 add_laned_object (track, lane, obj_ref);
103 return obj_ref.get_object_as<structure::arrangement::AudioRegion> ();
104 }
105
106 structure::arrangement::ScaleObject * add_scale_object (
109 double start_ticks)
110 {
111 auto obj_ref =
112 arranger_object_factory_
114 .with_start_ticks (start_ticks)
115 .with_scale (std::move (scale))
116 .build_in_registry ();
117 undo_stack_.push (
119 structure::arrangement::ScaleObject> (chord_track, obj_ref));
120 return obj_ref.get_object_as<structure::arrangement::ScaleObject> ();
121 }
122
123 structure::arrangement::AudioRegion * add_empty_audio_region_for_recording (
126 int num_channels,
127 const utils::Utf8String &clip_name,
128 double start_ticks)
129 {
130 auto region_ref =
131 arranger_object_factory_.create_empty_audio_region_for_recording (
132 num_channels, clip_name, start_ticks);
133 add_laned_object (track, lane, region_ref);
134 return region_ref.get_object_as<structure::arrangement::AudioRegion> ();
135 }
136
137 Q_INVOKABLE structure::arrangement::AudioRegion * addAudioRegionFromFile (
140 const QString &absPath,
141 double startTicks)
142 {
143 auto ar_ref = arranger_object_factory_.create_audio_region_from_file (
144 absPath, startTicks);
145 add_laned_object (*track, *lane, ar_ref);
146 return ar_ref.get_object_as<structure::arrangement::AudioRegion> ();
147 }
148
149 Q_INVOKABLE structure::arrangement::AudioRegion *
150 addAudioRegionToClipSlotFromFile (
151 structure::tracks::Track * track,
152 structure::scenes::ClipSlot * clipSlot,
153 const QString &absPath);
154 Q_INVOKABLE structure::arrangement::AudioRegion *
155 addMidiRegionToClipSlotFromFile (
156 structure::tracks::Track * track,
157 structure::scenes::ClipSlot * clipSlot,
158 const QString &absPath);
159
164 Q_INVOKABLE structure::arrangement::MidiRegion *
168 const dsp::ChordDescriptor &descr,
169 double startTicks);
170
182 const QString &absolutePath,
183 double startTicks,
184 int midiTrackIndex);
185
186 Q_INVOKABLE structure::arrangement::MidiNote * addMidiNote (
188 double startTicks,
189 int pitch);
190
191 Q_INVOKABLE structure::arrangement::AutomationPoint * addAutomationPoint (
193 double startTicks,
194 double value)
195
196 {
197 return add_editor_object (*region, startTicks, value);
198 }
199
200 Q_INVOKABLE structure::arrangement::ChordObject * addChordObject (
202 double startTicks,
203 const int chordIndex)
204
205 {
206 return add_editor_object (*region, startTicks, chordIndex);
207 }
208
209private:
213 void add_laned_object (
216 structure::arrangement::ArrangerObjectUuidReference obj_ref);
217
218 void add_object_to_clip_slot (
221 structure::arrangement::ArrangerObjectUuidReference obj_ref);
222
231 template <structure::arrangement::RegionObject RegionT>
232 auto add_editor_object (
233 RegionT &region,
234 double startTicks,
235 std::variant<int, double> value) -> RegionT::ArrangerObjectChildType *
236 requires (!std::is_same_v<RegionT, structure::arrangement::AudioRegion>)
237 {
238 using ChildT = typename RegionT::ArrangerObjectChildType;
239 auto obj_ref = arranger_object_factory_.create_editor_object<RegionT> (
240 startTicks, value);
241 undo_stack_.push (
242 new commands::AddArrangerObjectCommand<ChildT> (region, obj_ref));
243 auto obj = obj_ref.template get_object_as<ChildT> ();
244 return obj;
245 }
246
247private:
248 structure::arrangement::ArrangerObjectFactory &arranger_object_factory_;
249 dsp::SnapGrid &snap_grid_timeline_;
250 dsp::SnapGrid &snap_grid_editor_;
251 undo::UndoStack &undo_stack_;
252};
253} // namespace zrythm::actions
Q_INVOKABLE structure::arrangement::MidiRegion * addMidiRegionFromMidiFile(structure::tracks::Track *track, structure::tracks::TrackLane *lane, const QString &absolutePath, double startTicks, int midiTrackIndex)
Creates a MIDI region at lane from MIDI file path abs_path starting at startTicks.
structure::arrangement::AudioRegion * add_audio_region_with_clip(structure::tracks::Track &track, structure::tracks::TrackLane &lane, dsp::FileAudioSourceUuidReference clip_id, double start_ticks)
Q_INVOKABLE structure::arrangement::MidiRegion * addMidiRegionFromChordDescriptor(structure::tracks::Track *track, structure::tracks::TrackLane *lane, const dsp::ChordDescriptor &descr, double startTicks)
Creates a MIDI region at lane from the given descr starting at startTicks.
A ChordDescriptor describes a chord and is not linked to any specific object by itself.
Snap/grid information.
Definition snap_grid.h:22
auto create_editor_object(double startTicks, std::variant< int, double > value)
Used to create and add editor objects.
A region for playing back audio samples.
An automation point inside an AutomationTrack.
Represents an automation region, which contains a collection of automation points.
The ChordObject class represents a chord inside the chord editor.
Marker for the MarkerTrack.
Definition marker.h:16
A MIDI note inside a Region shown in the piano roll.
Definition midi_note.h:20
A Region containing MIDI events.
Definition midi_region.h:20
Manages tempo and time signature objects for a project.
The ChordTrack class is responsible for managing the chord and scale information in the project.
Definition chord_track.h:21
A container of MIDI or Audio regions.
Definition track_lane.h:28
Represents a track in the project.
Definition track.h:54
A unique pointer for QObject objects that also works with QObject-based ownership.
Definition qt.h:38
Lightweight UTF-8 string wrapper with safe conversions.
Definition utf8_string.h:38