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
10#include <farbot/RealtimeObject.hpp>
11#include <juce_audio_basics/juce_audio_basics.h>
12
13namespace zrythm::structure::tracks
14{
15
19class ClipPlaybackDataProvider final
20{
21 struct MidiCache
22 {
23 MidiCache (
24 juce::MidiMessageSequence &&midi_seq,
25 structure::tracks::ClipQuantizeOption quantize_opt,
26 units::precise_tick_t end_position)
27 : midi_seq_ (std::move (midi_seq)), quantize_opt_ (quantize_opt),
28 end_position_ (end_position)
29 {
30 }
31 juce::MidiMessageSequence midi_seq_;
32 structure::tracks::ClipQuantizeOption quantize_opt_;
33
37 units::precise_tick_t end_position_;
38 };
39
40 struct AudioCache
41 {
42 AudioCache (
43 juce::AudioSampleBuffer audio_buffer,
44 structure::tracks::ClipQuantizeOption quantize_opt,
45 units::precise_tick_t end_position)
46 : audio_buffer_ (std::move (audio_buffer)),
47 quantize_opt_ (quantize_opt), end_position_ (end_position)
48 {
49 }
50
51 juce::AudioSampleBuffer audio_buffer_;
52 structure::tracks::ClipQuantizeOption quantize_opt_;
53
57 units::precise_tick_t end_position_;
58 };
59
60public:
61 ClipPlaybackDataProvider (const dsp::TempoMap &tempo_map);
62
70 const arrangement::MidiRegion &midi_region,
71 structure::tracks::ClipQuantizeOption quantize_option);
72
79 const arrangement::AudioRegion &audio_region,
80 structure::tracks::ClipQuantizeOption quantize_option);
81
87 void
88 queue_stop_playback (structure::tracks::ClipQuantizeOption quantize_option);
89
90 // TrackEventProvider interface
91 void process_midi_events (
93 dsp::MidiEventVector &output_buffer) noexcept [[clang::nonblocking]];
94
100 std::span<float> left_buffer,
101 std::span<float> right_buffer) noexcept [[clang::nonblocking]];
102
106 auto playing () const { return playing_.load (); }
107
108 auto current_playback_position_in_clip () const
109 {
110 return internal_clip_buffer_position_.load ();
111 }
112
113private:
118 void update_playback_position (
119 const dsp::graph::EngineProcessTimeInfo &time_nfo,
120 units::sample_t clip_loop_end_samples);
121
125 std::pair<units::sample_t, units::sample_t> handle_quantization_and_start (
126 const dsp::graph::EngineProcessTimeInfo &time_nfo,
127 units::sample_t clip_loop_end_samples,
128 structure::tracks::ClipQuantizeOption quantize_opt);
129
133 template <typename ProcessFunc>
134 void process_chunks_with_looping (
135 units::sample_t internal_buffer_start_offset,
136 units::sample_t samples_to_process,
137 units::sample_t clip_loop_end_samples,
138 units::sample_t output_buffer_timestamp_offset,
139 ProcessFunc process_chunk);
140
146 void clear_active_buffers ();
147
148private:
150 farbot::RealtimeObject<
151 std::optional<MidiCache>,
152 farbot::RealtimeObjectOptions::nonRealtimeMutatable>
153 active_midi_playback_sequence_;
154
156 farbot::RealtimeObject<
157 std::optional<AudioCache>,
158 farbot::RealtimeObjectOptions::nonRealtimeMutatable>
159 active_audio_playback_buffer_;
160
161 const dsp::TempoMap &tempo_map_;
162
171 std::atomic<bool> playing_{ false };
172
180 bool was_playing_{ false };
181
188 std::atomic<units::sample_t> internal_clip_buffer_position_;
189
196 units::sample_t last_seen_timeline_position_;
197
204 units::sample_t clip_launch_timeline_position_;
205
206 static_assert (decltype (internal_clip_buffer_position_)::is_always_lock_free);
207};
208
209}
A lock-free thread-safe vector of MidiEvents.
Definition midi_event.h:74
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 dsp::graph::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 graph_node.h:51