Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
capture_engine.hpp
Go to the documentation of this file.
1#pragma once
2
9
10#include <array>
11#include <atomic>
12#include <cstddef>
13#include <cstdint>
14#include <span>
15#include <vector>
16
17namespace pulp::playback {
18
22 std::uint32_t input_channel = 0;
23 std::uint32_t output_channel = 0;
24 std::uint32_t channel_count = 0;
25 bool armed = false;
26 bool monitor = false;
27 bool capture_midi = false;
28};
29
31 static constexpr std::uint64_t kDefaultMaximumPreallocatedBytes = 512ull * 1024ull * 1024ull;
32
34 std::uint32_t maximum_block_size = 0;
35 std::uint64_t maximum_take_frames = 0;
36 std::uint32_t take_slots_per_track = 0;
37 std::uint32_t midi_events_per_take = 0;
39 std::vector<CaptureTrackConfig> tracks;
40};
41
55
57 std::uint32_t slot = 0;
58 std::uint32_t generation = 0;
59 constexpr auto operator<=>(const CaptureTakeHandle&) const = default;
60};
61
64 std::uint64_t take_frame = 0;
65};
66
67enum class CaptureCommandType : std::uint8_t {
72};
73
80
92
104
111
113 std::uint64_t completed_takes = 0;
114 std::uint64_t dropped_commands = 0;
115 std::uint64_t dropped_events = 0;
116 std::uint64_t capacity_failures = 0;
117};
118
123 public:
124 static constexpr std::size_t kMaximumTracks = 32;
125 static constexpr std::size_t kMaximumTakeSlotsPerTrack = 64;
126 static constexpr std::size_t kCommandQueueCapacity = 128;
127 static constexpr std::size_t kEventQueueCapacity = 256;
130
131 bool prepare(const CaptureEngineConfig& config);
132 void release() noexcept;
133
134 bool enqueue_command(const CaptureCommand& command) noexcept;
135 bool pop_event(CaptureEvent& event) noexcept;
136
137 CaptureProcessResult process(const audio::BufferView<const float>& input,
138 audio::BufferView<float>& monitor_output,
139 const midi::MidiBuffer& midi_input,
140 const TransportSnapshot& transport) noexcept;
141
142 bool copy_audio(CaptureTakeHandle take, audio::BufferView<float> destination) const noexcept;
143 bool copy_midi(CaptureTakeHandle take, std::span<CapturedMidiEvent> destination,
144 std::size_t& copied) const noexcept;
145
146 float input_peak(std::size_t track_index) const noexcept;
147 CaptureEngineStats stats() const noexcept;
148 bool recording() const noexcept;
149
150 private:
151 enum class SlotState : std::uint8_t { Free, Recording, Completed };
152
153 struct TakeSlot {
154 SlotState state = SlotState::Free;
155 std::uint32_t generation = 0;
156 std::uint32_t track_index = 0;
157 timebase::SamplePosition placement_start;
158 std::uint64_t frame_count = 0;
159 std::uint32_t midi_event_count = 0;
160 bool audio_capacity_reported = false;
161 bool midi_capacity_reported = false;
162 std::vector<float> audio;
163 std::vector<CapturedMidiEvent> midi;
164 };
165
166 struct TrackRuntime {
167 std::int32_t active_slot = -1;
168 bool capture_disabled = false;
169 };
170
171 static bool valid_config(const CaptureEngineConfig& config) noexcept;
172 static bool valid_session(const CaptureSession& session) noexcept;
173 static timebase::SamplePosition add_frames(timebase::SamplePosition start,
174 std::uint32_t frames) noexcept;
175
176 void apply_commands() noexcept;
177 void apply_command(const CaptureCommand& command) noexcept;
178 void start_session(const CaptureCommand& command) noexcept;
179 void stop_session(const CaptureCommand& command, bool cancelled) noexcept;
180 void release_take(CaptureTakeHandle take) noexcept;
181 void push_event(const CaptureEvent& event) noexcept;
182 void push_session_event(CaptureEventType type, std::uint64_t sequence) noexcept;
183 void monitor_inputs(const audio::BufferView<const float>& input,
184 audio::BufferView<float>& output, std::uint32_t frames) noexcept;
185 void render_metronome(audio::BufferView<float>& output,
186 const TransportSnapshot& transport) noexcept;
187 void process_range(const audio::BufferView<const float>& input,
188 const midi::MidiBuffer& midi_input, const TransportRange& range) noexcept;
189 void handle_range_boundary(const TransportRange& range) noexcept;
190 void finalize_active_takes() noexcept;
191 void cancel_active_takes() noexcept;
192 TakeSlot* begin_take(std::size_t track_index,
193 timebase::SamplePosition placement_start) noexcept;
194 void append_audio(TakeSlot& slot, const CaptureTrackConfig& track,
195 const audio::BufferView<const float>& input, std::uint32_t source_offset,
196 std::uint32_t frames) noexcept;
197 void append_midi(TakeSlot& slot, const midi::MidiBuffer& input, std::uint32_t source_offset,
198 std::uint32_t frames) noexcept;
199 bool valid_handle(CaptureTakeHandle take) const noexcept;
200
201 CaptureEngineConfig config_;
202 std::vector<TrackRuntime> track_runtime_;
203 std::vector<TakeSlot> slots_;
204 std::array<std::atomic<float>, kMaximumTracks> input_peaks_{};
205 runtime::SpscQueue<CaptureCommand, kCommandQueueCapacity> commands_;
206 runtime::SpscQueue<CaptureEvent, kEventQueueCapacity> events_;
207 CaptureSession session_;
208 std::uint64_t active_sequence_ = 0;
209 timebase::SamplePosition expected_timeline_sample_;
210 bool has_expected_timeline_sample_ = false;
211 bool recording_ = false;
212 bool prepared_ = false;
213 std::atomic<bool> recording_snapshot_{false};
214 std::atomic<std::uint64_t> completed_takes_{0};
215 std::atomic<std::uint64_t> dropped_commands_{0};
216 std::atomic<std::uint64_t> dropped_events_{0};
217 std::atomic<std::uint64_t> capacity_failures_{0};
218};
219
220static_assert(std::atomic<float>::is_always_lock_free);
221
222} // namespace pulp::playback
Fixed-capacity input recorder.
Definition capture_engine.hpp:122
static constexpr std::size_t kMaximumTakeSlotsPerTrack
Definition capture_engine.hpp:125
static constexpr std::size_t kMaximumTracks
Definition capture_engine.hpp:124
CaptureEngineStats stats() const noexcept
bool copy_audio(CaptureTakeHandle take, audio::BufferView< float > destination) const noexcept
bool enqueue_command(const CaptureCommand &command) noexcept
static constexpr std::size_t kEventQueueCapacity
Definition capture_engine.hpp:127
static constexpr std::size_t kCommandQueueCapacity
Definition capture_engine.hpp:126
float input_peak(std::size_t track_index) const noexcept
bool copy_midi(CaptureTakeHandle take, std::span< CapturedMidiEvent > destination, std::size_t &copied) const noexcept
bool pop_event(CaptureEvent &event) noexcept
static constexpr audio::RtSafetyClass process_rt_safety_class
Definition capture_engine.hpp:128
bool prepare(const CaptureEngineConfig &config)
CaptureProcessResult process(const audio::BufferView< const float > &input, audio::BufferView< float > &monitor_output, const midi::MidiBuffer &midi_input, const TransportSnapshot &transport) noexcept
bool recording() const noexcept
Definition analyzer_provider.hpp:12
RtSafetyClass
Definition rt_safety_contract.hpp:11
@ AudioCallbackSafeAfterPrepare
Definition rt_safety_contract.hpp:13
Definition custom_node_events.hpp:26
Definition audio_renderer.hpp:20
CaptureProcessResult
Definition capture_engine.hpp:105
@ InvalidBuffers
Definition capture_engine.hpp:108
CaptureCommandType
Definition capture_engine.hpp:67
@ Stop
Definition capture_engine.hpp:69
@ Start
Definition capture_engine.hpp:68
@ ReleaseTake
Definition capture_engine.hpp:71
@ Cancel
Definition capture_engine.hpp:70
CaptureEventType
Definition capture_engine.hpp:81
@ CommandRejected
Definition capture_engine.hpp:86
@ TakeCancelled
Definition capture_engine.hpp:90
@ TakeCapacityExceeded
Definition capture_engine.hpp:88
@ Started
Definition capture_engine.hpp:82
@ TakeCompleted
Definition capture_engine.hpp:83
@ MidiCapacityExceeded
Definition capture_engine.hpp:89
@ Cancelled
Definition capture_engine.hpp:85
@ Stopped
Definition capture_engine.hpp:84
@ NoFreeTakeSlot
Definition capture_engine.hpp:87
@ InvalidTransport
Definition audio_renderer.hpp:218
@ NotPrepared
Definition automation_recording.hpp:30
@ Ok
Definition automation_cursor.hpp:29
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
constexpr std::int64_t kTicksPerQuarter
Definition tick.hpp:54
STL namespace.
Timestamped MIDI event combining a choc::midi::ShortMessage with timing info.
Definition message.hpp:32
Definition capture_engine.hpp:74
CaptureSession session
Definition capture_engine.hpp:77
CaptureCommandType type
Definition capture_engine.hpp:75
CaptureTakeHandle take
Definition capture_engine.hpp:78
std::uint64_t sequence
Definition capture_engine.hpp:76
Definition capture_engine.hpp:30
std::uint32_t take_slots_per_track
Definition capture_engine.hpp:36
std::uint32_t maximum_block_size
Definition capture_engine.hpp:34
std::vector< CaptureTrackConfig > tracks
Definition capture_engine.hpp:39
std::uint64_t maximum_preallocated_bytes
Definition capture_engine.hpp:38
timebase::RationalRate sample_rate
Definition capture_engine.hpp:33
std::uint32_t midi_events_per_take
Definition capture_engine.hpp:37
std::uint64_t maximum_take_frames
Definition capture_engine.hpp:35
static constexpr std::uint64_t kDefaultMaximumPreallocatedBytes
Definition capture_engine.hpp:31
Definition capture_engine.hpp:112
std::uint64_t capacity_failures
Definition capture_engine.hpp:116
std::uint64_t dropped_commands
Definition capture_engine.hpp:114
std::uint64_t completed_takes
Definition capture_engine.hpp:113
std::uint64_t dropped_events
Definition capture_engine.hpp:115
Definition capture_engine.hpp:93
std::uint64_t frame_count
Definition capture_engine.hpp:100
std::uint32_t channel_count
Definition capture_engine.hpp:101
std::uint32_t midi_event_count
Definition capture_engine.hpp:102
timeline::ItemId track_id
Definition capture_engine.hpp:96
std::uint64_t sequence
Definition capture_engine.hpp:95
timeline::ItemId take_lane_id
Definition capture_engine.hpp:97
CaptureTakeHandle take
Definition capture_engine.hpp:98
CaptureEventType type
Definition capture_engine.hpp:94
timebase::SamplePosition placement_start
Definition capture_engine.hpp:99
Definition capture_engine.hpp:42
timebase::SamplePosition loop_end
Definition capture_engine.hpp:49
bool metronome_enabled
Definition capture_engine.hpp:50
bool has_punch_out
Definition capture_engine.hpp:45
bool loop_enabled
Definition capture_engine.hpp:47
timebase::SamplePosition punch_out
Definition capture_engine.hpp:46
timebase::TickDuration metronome_interval
Definition capture_engine.hpp:52
timebase::SamplePosition punch_in
Definition capture_engine.hpp:44
timebase::SamplePosition count_in_start
Definition capture_engine.hpp:43
float metronome_level
Definition capture_engine.hpp:53
std::uint32_t metronome_output_channel
Definition capture_engine.hpp:51
timebase::SamplePosition loop_start
Definition capture_engine.hpp:48
Definition capture_engine.hpp:56
constexpr auto operator<=>(const CaptureTakeHandle &) const =default
std::uint32_t generation
Definition capture_engine.hpp:58
std::uint32_t slot
Definition capture_engine.hpp:57
Definition capture_engine.hpp:19
bool armed
Definition capture_engine.hpp:25
std::uint32_t output_channel
Definition capture_engine.hpp:23
timeline::ItemId take_lane_id
Definition capture_engine.hpp:21
std::uint32_t input_channel
Definition capture_engine.hpp:22
std::uint32_t channel_count
Definition capture_engine.hpp:24
bool monitor
Definition capture_engine.hpp:26
timeline::ItemId track_id
Definition capture_engine.hpp:20
bool capture_midi
Definition capture_engine.hpp:27
Definition capture_engine.hpp:62
std::uint64_t take_frame
Definition capture_engine.hpp:64
midi::MidiEvent event
Definition capture_engine.hpp:63
Definition transport.hpp:71
Definition rational_time.hpp:14
Definition rational_time.hpp:9
Definition tick.hpp:56
Nonzero monotonic identity for a Timeline-owned object.
Definition item_id.hpp:19