Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
timeline_data_cache.h
1// SPDX-FileCopyrightText: © 2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "utils/units.h"
7
8#include <QObject>
9
10#include <juce_audio_basics/juce_audio_basics.h>
11
12namespace zrythm::dsp
13{
14
22class TimelineDataCache : public QObject
23{
24 Q_OBJECT
25
26public:
27 using IntervalType = std::pair<units::sample_t, units::sample_t>;
28
29 explicit TimelineDataCache (QObject * parent = nullptr) : QObject (parent) { }
30
31 ~TimelineDataCache () override;
32
36 void clear ()
37 {
38 clear_impl ();
39 Q_EMIT cachedRangesChanged (compute_cached_sample_ranges ());
40 }
41
54 virtual void remove_sequences_matching_interval (IntervalType interval) = 0;
55
64 {
65 finalize_changes_impl ();
66 Q_EMIT cachedRangesChanged (compute_cached_sample_ranges ());
67 }
68
74 virtual bool has_content () const = 0;
75
83 Q_SIGNAL void cachedRangesChanged (std::vector<IntervalType> ranges) const;
84
85protected:
90 static bool intervals_overlap (IntervalType a, IntervalType b) noexcept
91 {
92 return a.second > b.first && a.first < b.second;
93 }
94
95private:
96 virtual void clear_impl () = 0;
97 virtual void finalize_changes_impl () = 0;
98
102 virtual std::vector<IntervalType> compute_cached_sample_ranges () const = 0;
103};
104
111class MidiTimelineDataCache : public TimelineDataCache
112{
113public:
114 explicit MidiTimelineDataCache (QObject * parent = nullptr)
115 : TimelineDataCache (parent)
116 {
117 }
118
126 IntervalType interval,
127 const juce::MidiMessageSequence &sequence);
128
134 const juce::MidiMessageSequence &get_midi_events () const
135 {
136 return merged_midi_events_;
137 }
138
139 void remove_sequences_matching_interval (IntervalType interval) override;
140 bool has_content () const override;
141
142private:
143 void clear_impl () override;
144 void finalize_changes_impl () override;
145 std::vector<IntervalType> compute_cached_sample_ranges () const override;
152 std::map<IntervalType, juce::MidiMessageSequence> midi_sequences_;
153
160 juce::MidiMessageSequence merged_midi_events_;
161};
162
169class AudioTimelineDataCache : public TimelineDataCache
170{
171public:
172 explicit AudioTimelineDataCache (QObject * parent = nullptr)
173 : TimelineDataCache (parent)
174 {
175 }
176
185 {
187 juce::AudioSampleBuffer audio_buffer;
188
190 units::sample_t start_sample;
191
193 units::sample_t end_sample;
194 };
195
203 IntervalType interval,
204 const juce::AudioSampleBuffer &audio_buffer);
205
211 const std::vector<AudioRegionEntry> &get_audio_regions () const
212 {
213 return audio_regions_;
214 }
215
216 void remove_sequences_matching_interval (IntervalType interval) override;
217 bool has_content () const override;
218
219private:
220 void clear_impl () override;
221 void finalize_changes_impl () override;
222 std::vector<IntervalType> compute_cached_sample_ranges () const override;
229 std::vector<AudioRegionEntry> audio_regions_;
230};
231
238class AutomationTimelineDataCache : public TimelineDataCache
239{
240public:
241 explicit AutomationTimelineDataCache (QObject * parent = nullptr)
242 : TimelineDataCache (parent)
243 {
244 }
245
254 {
256 std::vector<float> automation_values;
257
259 units::sample_t start_sample;
260
262 units::sample_t end_sample;
263 };
264
272 IntervalType interval,
273 const std::vector<float> &automation_values);
274
280 const std::vector<AutomationCacheEntry> &get_automation_sequences () const
281 {
282 return automation_sequences_;
283 }
284
285 void remove_sequences_matching_interval (IntervalType interval) override;
286 bool has_content () const override;
287
288private:
289 void clear_impl () override;
290 void finalize_changes_impl () override;
291 std::vector<IntervalType> compute_cached_sample_ranges () const override;
298 std::vector<AutomationCacheEntry> automation_sequences_;
299};
300
301} // namespace zrythm::dsp
302
303Q_DECLARE_METATYPE (std::vector<zrythm::dsp::TimelineDataCache::IntervalType>)
void add_audio_region(IntervalType interval, const juce::AudioSampleBuffer &audio_buffer)
Adds an audio region for the given interval.
void remove_sequences_matching_interval(IntervalType interval) override
Removes cached data for intervals that truly overlap with the given interval.
const std::vector< AudioRegionEntry > & get_audio_regions() const
Gets the cached audio regions.
bool has_content() const override
Checks if the cache has any content.
void add_automation_sequence(IntervalType interval, const std::vector< float > &automation_values)
Adds an automation sequence for the given interval.
void remove_sequences_matching_interval(IntervalType interval) override
Removes cached data for intervals that truly overlap with the given interval.
bool has_content() const override
Checks if the cache has any content.
const std::vector< AutomationCacheEntry > & get_automation_sequences() const
Gets the cached automation sequences.
const juce::MidiMessageSequence & get_midi_events() const
Gets the cached MIDI events.
void add_midi_sequence(IntervalType interval, const juce::MidiMessageSequence &sequence)
Adds a MIDI sequence for the given interval.
void remove_sequences_matching_interval(IntervalType interval) override
Removes cached data for intervals that truly overlap with the given interval.
bool has_content() const override
Checks if the cache has any content.
void finalize_changes()
Finalizes changes, prepares cached data for access, and emits cachedRangesChanged.
virtual bool has_content() const =0
Checks if the cache has any content.
Q_SIGNAL void cachedRangesChanged(std::vector< IntervalType > ranges) const
Emitted when the cache content changes (after finalize_changes or clear).
static bool intervals_overlap(IntervalType a, IntervalType b) noexcept
Returns true if two intervals truly overlap (adjacent intervals do not count).
virtual void remove_sequences_matching_interval(IntervalType interval)=0
Removes cached data for intervals that truly overlap with the given interval.
void clear()
Clears all cached data and emits cachedRangesChanged.
units::sample_t end_sample
End position in samples.
juce::AudioSampleBuffer audio_buffer
Copy of the audio sample buffer.
units::sample_t start_sample
Start position in samples.
std::vector< float > automation_values
Automation values for the parameter.