6#include "structure/arrangement/audio_clip.h"
7#include "structure/arrangement/audio_source_object.h"
8#include "structure/arrangement/automation_clip.h"
9#include "structure/arrangement/chord_clip.h"
10#include "structure/arrangement/chord_object.h"
11#include "structure/arrangement/marker.h"
12#include "structure/arrangement/midi_clip.h"
13#include "structure/arrangement/midi_control_event.h"
14#include "structure/arrangement/midi_note.h"
15#include "structure/arrangement/scale_object.h"
16#include "structure/arrangement/tempo_object.h"
17#include "structure/arrangement/time_signature_object.h"
19namespace zrythm::structure::arrangement
22template <FinalArrangerObjectSub
class ObjT>
24is_arranger_object_deletable (
const ObjT &obj)
26 if constexpr (std::is_same_v<ObjT, Marker>)
46template <ClipObject ObjectT>
47[[gnu::nonnull]] std::pair<int64_t, bool>
48get_frames_till_next_loop_or_end (
50 int64_t timeline_frames)
52 const auto loop_size = obj.get_loop_length_in_frames ();
53 assert (loop_size > 0);
54 const auto object_position_frames = obj.position ()->samples ();
55 const int64_t loop_end_frames =
56 obj.loopEndPosition ()->samples ();
57 const int64_t clip_start_frames =
58 obj.clipStartPosition ()->samples ();
60 int64_t local_frames = timeline_frames - object_position_frames;
61 local_frames += clip_start_frames;
62 while (local_frames >= loop_end_frames)
64 local_frames -= loop_size;
67 const int64_t frames_till_next_loop = loop_end_frames - local_frames;
68 const int64_t frames_till_end =
69 obj.get_end_position_samples (
true) - timeline_frames;
71 return std::make_pair (
72 std::min (frames_till_end, frames_till_next_loop),
73 frames_till_next_loop < frames_till_end);
84 return qobject_cast<const Clip *> (&obj) !=
nullptr;
97inline dsp::TimelineTick
100 const auto * parent = obj.parentObject ();
101 if (parent !=
nullptr)
103 if (
const auto * clip = qobject_cast<const Clip *> (parent))
105 return clip->contentWarp ()->contentToTimeline (
106 qobject_cast<const dsp::ContentPosition *> (obj.position ())
110 return dsp::TimelineTick{ units::ticks (obj.position ()->ticks ()) };
120inline dsp::TimelineTick
123 if (obj.length () ==
nullptr)
124 return timeline_ticks (obj);
126 const auto * parent = obj.parentObject ();
127 if (parent !=
nullptr)
129 if (
const auto * clip = qobject_cast<const Clip *> (parent))
131 const auto content_pos =
132 qobject_cast<const dsp::ContentPosition *> (obj.position ())
134 return clip->contentWarp ()->contentToTimeline (
135 content_pos + obj.length ()->asTick ());
139 if (
const auto * clip = qobject_cast<const Clip *> (&obj))
141 return clip->contentWarp ()->contentToTimeline (
142 clip->length ()->asTick ());
146 return dsp::TimelineTick{
147 units::ticks (obj.position ()->ticks () + obj.length ()->ticks ())
154 return std::make_pair (
155 timeline_ticks (*obj).asDouble (), timeline_end_ticks (*obj).asDouble ());
167set_end_from_timeline_ticks (
ArrangerObject &obj, dsp::TimelineTick timeline_end)
169 if (obj.length () ==
nullptr)
173 const auto * parent = obj.parentObject ();
174 if (parent !=
nullptr)
176 if (
const auto * parent_clip = qobject_cast<const Clip *> (parent))
178 const auto content_end =
179 parent_clip->contentWarp ()->timelineToContent (timeline_end);
180 const auto content_pos =
181 qobject_cast<const dsp::ContentPosition *> (obj.position ())
183 obj.length ()->setTicks ((content_end - content_pos).asDouble ());
189 if (
auto * clip = qobject_cast<Clip *> (&obj))
191 const auto content_end =
192 clip->contentWarp ()->timelineToContent (timeline_end);
193 clip->length ()->setTicks (content_end.asDouble ());
198 obj.length ()->setTicks (
199 (timeline_end - dsp::TimelineTick{ units::ticks (obj.position ()->ticks ()) })
Base class for all objects in the arranger.
void clip(std::span< float > buf, float minf, float maxf)
Clamp the buffer to min/max.