Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
clip_playback_data_provider.h
1// SPDX-FileCopyrightText: © 2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include <atomic>
7
8#include "structure/tracks/track_fwd.h"
9#include "utils/types.h"
10
11#include <farbot/RealtimeObject.hpp>
12#include <juce_wrapper.h>
13
14namespace zrythm::structure::tracks
15{
16
20class ClipPlaybackDataProvider final
21{
22 struct MidiCache
23 {
24 MidiCache (
25 juce::MidiMessageSequence &&midi_seq,
26 structure::tracks::ClipQuantizeOption quantize_opt,
27 units::precise_tick_t end_position)
28 : midi_seq_ (std::move (midi_seq)), quantize_opt_ (quantize_opt),
29 end_position_ (end_position)
30 {
31 }
32 juce::MidiMessageSequence midi_seq_;
33 structure::tracks::ClipQuantizeOption quantize_opt_;
34
38 units::precise_tick_t end_position_;
39 };
40
41 struct AudioCache
42 {
43 AudioCache (
44 juce::AudioSampleBuffer audio_buffer,
45 structure::tracks::ClipQuantizeOption quantize_opt,
46 units::precise_tick_t end_position)
47 : audio_buffer_ (std::move (audio_buffer)),
48 quantize_opt_ (quantize_opt), end_position_ (end_position)
49 {
50 }
51
52 juce::AudioSampleBuffer audio_buffer_;
53 structure::tracks::ClipQuantizeOption quantize_opt_;
54
58 units::precise_tick_t end_position_;
59 };
60
61public:
62 ClipPlaybackDataProvider (const dsp::TempoMap &tempo_map);
63
71 const arrangement::MidiRegion &midi_region,
72 structure::tracks::ClipQuantizeOption quantize_option);
73
80 const arrangement::AudioRegion &audio_region,
81 structure::tracks::ClipQuantizeOption quantize_option);
82
88 void
89 queue_stop_playback (structure::tracks::ClipQuantizeOption quantize_option);
90
91 // TrackEventProvider interface
92 void process_midi_events (
93 const EngineProcessTimeInfo &time_nfo,
94 dsp::MidiEventVector &output_buffer) noexcept [[clang::nonblocking]];
95
100 const EngineProcessTimeInfo &time_nfo,
101 std::span<float> left_buffer,
102 std::span<float> right_buffer) noexcept [[clang::nonblocking]];
103
107 auto playing () const { return playing_.load (); }
108
109 auto current_playback_position_in_clip () const
110 {
111 return internal_clip_buffer_position_.load ();
112 }
113
114private:
119 void update_playback_position (
120 const EngineProcessTimeInfo &time_nfo,
121 units::sample_t clip_loop_end_samples);
122
126 std::pair<units::sample_t, units::sample_t> handle_quantization_and_start (
127 const EngineProcessTimeInfo &time_nfo,
128 units::sample_t clip_loop_end_samples,
129 structure::tracks::ClipQuantizeOption quantize_opt);
130
134 template <typename ProcessFunc>
135 void process_chunks_with_looping (
136 units::sample_t internal_buffer_start_offset,
137 units::sample_t samples_to_process,
138 units::sample_t clip_loop_end_samples,
139 units::sample_t output_buffer_timestamp_offset,
140 ProcessFunc process_chunk);
141
147 void clear_active_buffers ();
148
149private:
151 farbot::RealtimeObject<
152 std::optional<MidiCache>,
153 farbot::RealtimeObjectOptions::nonRealtimeMutatable>
154 active_midi_playback_sequence_;
155
157 farbot::RealtimeObject<
158 std::optional<AudioCache>,
159 farbot::RealtimeObjectOptions::nonRealtimeMutatable>
160 active_audio_playback_buffer_;
161
162 const dsp::TempoMap &tempo_map_;
163
172 std::atomic<bool> playing_{ false };
173
181 bool was_playing_{ false };
182
189 std::atomic<units::sample_t> internal_clip_buffer_position_;
190
197 units::sample_t last_seen_timeline_position_;
198
205 units::sample_t clip_launch_timeline_position_;
206
207 static_assert (decltype (internal_clip_buffer_position_)::is_always_lock_free);
208};
209
210}
A lock-free thread-safe vector of MidiEvents.
Definition midi_event.h:78
A region for playing back audio samples.
A Region containing MIDI events.
Definition midi_region.h:20
void queue_stop_playback(structure::tracks::ClipQuantizeOption quantize_option)
Requests that playback is stopped at the next quantization point.
auto playing() const
Whether currently playing any part of the clip.
void generate_audio_events(const arrangement::AudioRegion &audio_region, structure::tracks::ClipQuantizeOption quantize_option)
Generate the audio buffer to be used during realtime processing.
void process_audio_events(const EngineProcessTimeInfo &time_nfo, std::span< float > left_buffer, std::span< float > right_buffer) noexcept
Process audio events for clip launcher playback.
void generate_midi_events(const arrangement::MidiRegion &midi_region, structure::tracks::ClipQuantizeOption quantize_option)
Generate the MIDI event sequence to be used during realtime processing.
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition types.h:133