Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
automation_cursor.hpp
Go to the documentation of this file.
1#pragma once
2
6
7#include <cstddef>
8#include <cstdint>
9#include <iterator>
10#include <limits>
11#include <span>
12
13namespace pulp::playback {
14
15enum class AutomationTransition : std::uint8_t {
19};
20
22 std::uint32_t sample_offset = 0;
23 float value = 0.0f;
25 constexpr bool operator==(const AutomationBlockEvent&) const = default;
26};
27
37
43
54
59 public:
60 using Reader = AutomationProgramSegment (*)(const void*, std::size_t) noexcept;
61
62 class Iterator {
63 public:
64 using iterator_category = std::random_access_iterator_tag;
65 using iterator_concept = std::random_access_iterator_tag;
67 using difference_type = std::ptrdiff_t;
69
70 reference operator*() const noexcept {
71 return (*view_)[index_];
72 }
73 reference operator[](difference_type offset) const noexcept {
74 return (
75 *view_)[static_cast<std::size_t>(static_cast<difference_type>(index_) + offset)];
76 }
77 Iterator& operator++() noexcept {
78 ++index_;
79 return *this;
80 }
81 Iterator operator++(int) noexcept {
82 auto copy = *this;
83 ++*this;
84 return copy;
85 }
86 Iterator& operator--() noexcept {
87 --index_;
88 return *this;
89 }
90 Iterator operator--(int) noexcept {
91 auto copy = *this;
92 --*this;
93 return copy;
94 }
95 Iterator& operator+=(difference_type offset) noexcept {
96 index_ = static_cast<std::size_t>(static_cast<difference_type>(index_) + offset);
97 return *this;
98 }
99 Iterator& operator-=(difference_type offset) noexcept {
100 return *this += -offset;
101 }
102 friend Iterator operator+(Iterator iterator, difference_type offset) noexcept {
103 return iterator += offset;
104 }
105 friend Iterator operator+(difference_type offset, Iterator iterator) noexcept {
106 return iterator += offset;
107 }
108 friend Iterator operator-(Iterator iterator, difference_type offset) noexcept {
109 return iterator -= offset;
110 }
111 friend difference_type operator-(const Iterator& lhs, const Iterator& rhs) noexcept {
112 return static_cast<difference_type>(lhs.index_) -
113 static_cast<difference_type>(rhs.index_);
114 }
115 auto operator<=>(const Iterator&) const = default;
116
117 private:
119 Iterator(const AutomationSegmentView* view, std::size_t index) noexcept
120 : view_(view), index_(index) {}
121 const AutomationSegmentView* view_ = nullptr;
122 std::size_t index_ = 0;
123 };
124
125 constexpr AutomationSegmentView() noexcept = default;
126
127 AutomationProgramSegment operator[](std::size_t index) const noexcept {
128 return reader_(records_, index);
129 }
131 return (*this)[0];
132 }
134 return (*this)[count_ - 1u];
135 }
136 Iterator begin() const noexcept {
137 return Iterator(this, 0);
138 }
139 Iterator end() const noexcept {
140 return Iterator(this, count_);
141 }
142 std::size_t size() const noexcept {
143 return count_;
144 }
145 bool empty() const noexcept {
146 return count_ == 0;
147 }
148 AutomationSegmentView subspan(std::size_t offset, std::size_t count) const noexcept {
149 return {static_cast<const std::byte*>(records_) + offset * record_stride_, count, reader_,
150 record_stride_};
151 }
152
153 template <typename Record>
154 static AutomationSegmentView from_records(std::span<const Record> records,
155 Reader reader) noexcept {
156 return {records.data(), records.size(), reader, sizeof(Record)};
157 }
158
159 private:
160 constexpr AutomationSegmentView(const void* records, std::size_t count, Reader reader,
161 std::size_t record_stride) noexcept
162 : records_(records), count_(count), reader_(reader), record_stride_(record_stride) {}
163
164 const void* records_ = nullptr;
165 std::size_t count_ = 0;
166 Reader reader_ = nullptr;
167 std::size_t record_stride_ = 0;
168};
169
174 public:
182
183 static AutomationProgramView from(const AutomationProgram& program) noexcept;
184
185 ProgramGeneration generation() const noexcept {
186 return generation_;
187 }
189 return instance_token_;
190 }
191 timeline::ItemId lane_id() const noexcept {
192 return lane_id_;
193 }
194 const timebase::CompiledTempoMap& tempo_map() const noexcept {
195 return *tempo_map_;
196 }
198 return segments_;
199 }
200 float leading_value() const noexcept {
201 return leading_value_;
202 }
203 bool empty() const noexcept {
204 return segments_.empty();
205 }
206
207 private:
208 ProgramGeneration generation_ = 0;
209 AutomationProgramInstanceToken instance_token_;
210 timeline::ItemId lane_id_;
211 const timebase::CompiledTempoMap* tempo_map_ = nullptr;
212 AutomationSegmentView segments_;
213 float leading_value_ = 0.0f;
214};
215
222 public:
225
227 const TransportSnapshot& transport,
228 std::span<AutomationBlockEvent> output,
229 std::uint32_t max_intersecting_segments =
230 std::numeric_limits<std::uint32_t>::max()) noexcept;
232 const TransportSnapshot& transport,
233 std::span<AutomationBlockEvent> output,
234 std::uint32_t max_intersecting_segments =
235 std::numeric_limits<std::uint32_t>::max()) noexcept;
236 void reset() noexcept;
237
238 timeline::ItemId active_lane_id() const noexcept {
239 return active_key_.item_id;
240 }
242 return active_key_.generation;
243 }
244
245 private:
246 RendererProgramKey active_key_;
247 AutomationProgramInstanceToken active_instance_token_;
248 bool has_block_index_ = false;
249 std::uint64_t last_block_index_ = 0;
250};
251
252} // namespace pulp::playback
Allocation-free renderer for one immutable AutomationProgram.
Definition automation_cursor.hpp:221
static constexpr audio::RtSafetyClass process_rt_safety_class
Definition automation_cursor.hpp:223
AutomationCursorResult process(const AutomationProgram &program, const TransportSnapshot &transport, std::span< AutomationBlockEvent > output, std::uint32_t max_intersecting_segments=std::numeric_limits< std::uint32_t >::max()) noexcept
timeline::ItemId active_lane_id() const noexcept
Definition automation_cursor.hpp:238
ProgramGeneration active_generation() const noexcept
Definition automation_cursor.hpp:241
The identity, exact tempo-map object, and immutable segments consumed by AutomationCursor.
Definition automation_cursor.hpp:173
float leading_value() const noexcept
Definition automation_cursor.hpp:200
timeline::ItemId lane_id() const noexcept
Definition automation_cursor.hpp:191
AutomationProgramInstanceToken instance_token() const noexcept
Definition automation_cursor.hpp:188
const timebase::CompiledTempoMap & tempo_map() const noexcept
Definition automation_cursor.hpp:194
static AutomationProgramView from(const AutomationProgram &program) noexcept
AutomationProgramView(ProgramGeneration generation, AutomationProgramInstanceToken instance_token, timeline::ItemId lane_id, const timebase::CompiledTempoMap &tempo_map, AutomationSegmentView segments, float leading_value) noexcept
Definition automation_cursor.hpp:176
ProgramGeneration generation() const noexcept
Definition automation_cursor.hpp:185
AutomationSegmentView segments() const noexcept
Definition automation_cursor.hpp:197
bool empty() const noexcept
Definition automation_cursor.hpp:203
Immutable tick- and sample-domain form of one automation lane.
Definition automation_program.hpp:55
Definition automation_cursor.hpp:62
Iterator & operator-=(difference_type offset) noexcept
Definition automation_cursor.hpp:99
Iterator operator++(int) noexcept
Definition automation_cursor.hpp:81
AutomationProgramSegment reference
Definition automation_cursor.hpp:68
friend Iterator operator+(Iterator iterator, difference_type offset) noexcept
Definition automation_cursor.hpp:102
friend Iterator operator+(difference_type offset, Iterator iterator) noexcept
Definition automation_cursor.hpp:105
Iterator & operator--() noexcept
Definition automation_cursor.hpp:86
Iterator operator--(int) noexcept
Definition automation_cursor.hpp:90
friend difference_type operator-(const Iterator &lhs, const Iterator &rhs) noexcept
Definition automation_cursor.hpp:111
reference operator[](difference_type offset) const noexcept
Definition automation_cursor.hpp:73
friend class AutomationSegmentView
Definition automation_cursor.hpp:118
std::ptrdiff_t difference_type
Definition automation_cursor.hpp:67
friend Iterator operator-(Iterator iterator, difference_type offset) noexcept
Definition automation_cursor.hpp:108
Iterator & operator+=(difference_type offset) noexcept
Definition automation_cursor.hpp:95
auto operator<=>(const Iterator &) const =default
AutomationProgramSegment value_type
Definition automation_cursor.hpp:66
reference operator*() const noexcept
Definition automation_cursor.hpp:70
std::random_access_iterator_tag iterator_category
Definition automation_cursor.hpp:64
Iterator & operator++() noexcept
Definition automation_cursor.hpp:77
std::random_access_iterator_tag iterator_concept
Definition automation_cursor.hpp:65
Random-access, immutable segment storage used by the production cursor.
Definition automation_cursor.hpp:58
bool empty() const noexcept
Definition automation_cursor.hpp:145
AutomationProgramSegment front() const noexcept
Definition automation_cursor.hpp:130
AutomationSegmentView subspan(std::size_t offset, std::size_t count) const noexcept
Definition automation_cursor.hpp:148
AutomationProgramSegment(*)(const void *, std::size_t) noexcept Reader
Definition automation_cursor.hpp:60
Iterator end() const noexcept
Definition automation_cursor.hpp:139
std::size_t size() const noexcept
Definition automation_cursor.hpp:142
constexpr AutomationSegmentView() noexcept=default
static AutomationSegmentView from_records(std::span< const Record > records, Reader reader) noexcept
Definition automation_cursor.hpp:154
Iterator begin() const noexcept
Definition automation_cursor.hpp:136
AutomationProgramSegment back() const noexcept
Definition automation_cursor.hpp:133
Definition compiled_tempo_map.hpp:91
RtSafetyClass
Definition rt_safety_contract.hpp:11
@ AudioCallbackSafeWithImmutableInputs
Definition rt_safety_contract.hpp:14
Definition audio_renderer.hpp:20
@ InvalidTransport
Definition audio_renderer.hpp:218
AutomationTransition
Definition automation_cursor.hpp:15
@ Immediate
Definition automation_cursor.hpp:17
@ LinearRamp
Definition automation_cursor.hpp:18
@ Seed
Definition automation_cursor.hpp:16
AutomationProgramAdoption
Definition automation_cursor.hpp:38
@ Unchanged
Definition automation_cursor.hpp:40
@ Adopted
Definition automation_cursor.hpp:39
@ Rejected
Definition automation_cursor.hpp:41
AutomationCursorCode
Definition automation_cursor.hpp:28
@ Coalesced
Definition automation_cursor.hpp:30
@ InsufficientCapacity
Definition automation_cursor.hpp:34
@ WorkCapacityExceeded
Definition automation_cursor.hpp:35
@ TempoMapMismatch
Definition automation_cursor.hpp:33
@ AdoptionRejected
Definition automation_cursor.hpp:31
@ Ok
Definition automation_cursor.hpp:29
std::uint64_t ProgramGeneration
Definition program_identity.hpp:10
Definition program_compiler.hpp:18
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
STL namespace.
Definition automation_cursor.hpp:21
constexpr bool operator==(const AutomationBlockEvent &) const =default
float value
Definition automation_cursor.hpp:23
std::uint32_t sample_offset
Definition automation_cursor.hpp:22
AutomationTransition transition
Definition automation_cursor.hpp:24
Definition automation_cursor.hpp:44
AutomationProgramAdoption adoption
Definition automation_cursor.hpp:46
AutomationCursorCode code
Definition automation_cursor.hpp:45
std::uint32_t candidate_points
Distinct mandatory topology and continuous-refinement positions before applying the caller's output b...
Definition automation_cursor.hpp:50
std::uint32_t emitted_events
Definition automation_cursor.hpp:47
std::uint32_t intersecting_segments
Compiled segments intersecting the active transport ranges.
Definition automation_cursor.hpp:52
Definition automation_program.hpp:21
Definition automation_program.hpp:38
Definition program_identity.hpp:12
Definition transport.hpp:71
Nonzero monotonic identity for a Timeline-owned object.
Definition item_id.hpp:19