Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
rolling_audio_capture_buffer.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <atomic>
4#include <cstdint>
5#include <vector>
6
9
10namespace pulp::audio {
11
13
15 std::uint32_t num_channels = 0;
16 std::uint64_t max_frames = 0;
17 std::uint64_t bytes_per_sample = sizeof(float);
18};
19
21 bool ok = false;
22 std::uint64_t requested_frames = 0;
23 std::uint64_t allocated_frames = 0;
24 std::uint64_t allocated_bytes = 0;
25};
26
28 bool valid = false;
29 std::uint64_t generation = 0;
30 std::uint32_t num_channels = 0;
31 std::uint64_t capacity_frames = 0;
32 std::uint64_t start_frame = 0;
33 std::uint64_t frame_count = 0;
34 std::uint64_t end_frame = 0;
35};
36
43
49
51public:
58
59 bool valid() const noexcept { return buffer_ != nullptr && snapshot_.valid; }
60 const RollingAudioCaptureSnapshot& snapshot() const noexcept { return snapshot_; }
61 void release() noexcept;
62
63private:
65
68 std::uint64_t hold_id) noexcept;
69
70 RollingAudioCaptureBuffer* buffer_ = nullptr;
72 std::uint64_t hold_id_ = 0;
73};
74
76public:
78
81 double sample_rate,
82 double seconds,
83 std::uint64_t max_bytes = 0);
84 void reset() noexcept;
85
86 std::uint32_t num_channels() const noexcept { return num_channels_; }
87 std::uint64_t capacity_frames() const noexcept { return capacity_frames_; }
88 std::uint64_t allocated_bytes() const noexcept;
89 std::uint64_t frames_discarded_while_held() const noexcept {
90 return frames_discarded_while_held_.load(std::memory_order_relaxed);
91 }
92
93 void append(BufferView<const float> source, std::uint64_t frames) noexcept;
94 void append(BufferView<float> source, std::uint64_t frames) noexcept;
95
96 RollingAudioCaptureSnapshot snapshot_last(std::uint64_t frames) const noexcept;
97
98 // Live-freeze protocol. hold_last() is the preferred controller/owner
99 // shape: the returned token releases the held storage in its destructor.
100 // begin_hold_last(), end_hold(), append(), prepare(), and reset() remain
101 // capture-owner operations for lower-level/manual integrations; call them
102 // from the owner that calls append(), typically the audio thread at a block
103 // boundary. While the hold is active, append() is a no-op and incoming
104 // frames are intentionally discarded so off-RT materialization can copy the
105 // held snapshot without racing rolling storage overwrite. The discarded
106 // frame count is observable through frames_discarded_while_held().
107 RollingAudioCaptureHold hold_last(std::uint64_t frames) noexcept;
108 RollingAudioCaptureSnapshot begin_hold_last(std::uint64_t frames) noexcept;
109 bool hold_active() const noexcept;
110 void end_hold() noexcept;
112 const RollingAudioCaptureHold& hold,
113 BufferView<float> destination) const noexcept;
116 BufferView<float> destination) const noexcept;
117
118 // Off-real-time helper. The capture buffer must be paused/quiescent or
119 // externally protected while materializing; the descriptor alone does not
120 // pin the rolling storage against concurrent overwrite.
123 BufferView<float> destination) const noexcept;
124 [[deprecated("Use materialize_quiescent(); this path requires paused/external synchronization")]]
127 BufferView<float> destination) const noexcept;
128
129 static std::uint64_t estimate_bytes(std::uint32_t num_channels,
130 std::uint64_t frames,
131 std::uint64_t bytes_per_sample = sizeof(float)) noexcept;
132
133private:
135
136 struct CursorState {
137 std::uint64_t total_written = 0;
138 std::uint64_t write_pos = 0;
139 std::uint64_t generation = 0;
140 };
141
142 void clear_unprepared() noexcept;
143 void advance_generation() noexcept;
144 std::uint64_t next_hold_id() noexcept;
145 void end_hold_if_current(const RollingAudioCaptureSnapshot& snapshot,
146 std::uint64_t hold_id) noexcept;
147
148 template<typename SampleType>
149 void append_impl(BufferView<SampleType> source, std::uint64_t frames) noexcept;
150
151 bool snapshot_available(const RollingAudioCaptureSnapshot& snapshot,
152 CursorState state) const noexcept;
153 float* channel_storage(std::uint32_t channel) noexcept;
154 const float* channel_storage(std::uint32_t channel) const noexcept;
155
156 std::vector<float> storage_;
157 std::uint32_t num_channels_ = 0;
158 std::uint64_t capacity_frames_ = 0;
159 std::uint64_t write_pos_ = 0;
160 std::uint64_t total_written_ = 0;
161 std::uint64_t generation_ = 1;
162 RollingAudioCaptureSnapshot held_snapshot_;
163 std::uint64_t active_hold_id_ = 0;
164 std::uint64_t next_hold_id_ = 1;
165 std::atomic<std::uint64_t> frames_discarded_while_held_{0};
166 std::atomic_bool hold_active_{false};
167 runtime::SeqLock<CursorState> state_;
168};
169
170} // namespace pulp::audio
Non-owning view over multi-channel audio sample data.
Definition buffer.hpp:30
Definition rolling_audio_capture_buffer.hpp:75
friend class RollingAudioCaptureHold
Definition rolling_audio_capture_buffer.hpp:134
std::uint64_t allocated_bytes() const noexcept
RollingAudioCaptureSnapshot snapshot_last(std::uint64_t frames) const noexcept
std::uint64_t capacity_frames() const noexcept
Definition rolling_audio_capture_buffer.hpp:87
void append(BufferView< const float > source, std::uint64_t frames) noexcept
void append(BufferView< float > source, std::uint64_t frames) noexcept
static std::uint64_t estimate_bytes(std::uint32_t num_channels, std::uint64_t frames, std::uint64_t bytes_per_sample=sizeof(float)) noexcept
RollingAudioCaptureMaterializeResult materialize_quiescent(const RollingAudioCaptureSnapshot &snapshot, BufferView< float > destination) const noexcept
RollingAudioCaptureMaterializeResult materialize(const RollingAudioCaptureSnapshot &snapshot, BufferView< float > destination) const noexcept
RollingAudioCapturePrepareResult prepare_seconds(std::uint32_t num_channels, double sample_rate, double seconds, std::uint64_t max_bytes=0)
std::uint32_t num_channels() const noexcept
Definition rolling_audio_capture_buffer.hpp:86
RollingAudioCaptureSnapshot begin_hold_last(std::uint64_t frames) noexcept
RollingAudioCaptureMaterializeResult materialize_held(const RollingAudioCaptureHold &hold, BufferView< float > destination) const noexcept
RollingAudioCaptureHold hold_last(std::uint64_t frames) noexcept
std::uint64_t frames_discarded_while_held() const noexcept
Definition rolling_audio_capture_buffer.hpp:89
bool prepare(const RollingAudioCaptureBufferConfig &config)
RollingAudioCaptureHold(const RollingAudioCaptureHold &)=delete
bool valid() const noexcept
Definition rolling_audio_capture_buffer.hpp:59
RollingAudioCaptureHold(RollingAudioCaptureHold &&other) noexcept
RollingAudioCaptureHold & operator=(RollingAudioCaptureHold &&other) noexcept
const RollingAudioCaptureSnapshot & snapshot() const noexcept
Definition rolling_audio_capture_buffer.hpp:60
friend class RollingAudioCaptureBuffer
Definition rolling_audio_capture_buffer.hpp:64
RollingAudioCaptureHold & operator=(const RollingAudioCaptureHold &)=delete
Definition analyzer_provider.hpp:12
RollingAudioCaptureMaterializeStatus
Definition rolling_audio_capture_buffer.hpp:37
@ Overwritten
Definition rolling_audio_capture_buffer.hpp:40
@ DestinationTooSmall
Definition rolling_audio_capture_buffer.hpp:41
@ InvalidSnapshot
Definition rolling_audio_capture_buffer.hpp:39
@ Ok
Definition loop_types.hpp:34
constexpr std::size_t bytes_per_sample(SampleFormat format) noexcept
Bytes per sample for format. Returns 0 for unknown values.
Definition sample_converter.hpp:61
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
STL namespace.
Lock-free sequence-lock for coherent multi-field snapshots.
Definition rolling_audio_capture_buffer.hpp:14
std::uint32_t num_channels
Definition rolling_audio_capture_buffer.hpp:15
std::uint64_t max_frames
Definition rolling_audio_capture_buffer.hpp:16
std::uint64_t bytes_per_sample
Definition rolling_audio_capture_buffer.hpp:17
Definition rolling_audio_capture_buffer.hpp:44
std::uint64_t frames_copied
Definition rolling_audio_capture_buffer.hpp:47
RollingAudioCaptureMaterializeStatus status
Definition rolling_audio_capture_buffer.hpp:45
Definition rolling_audio_capture_buffer.hpp:20
std::uint64_t allocated_bytes
Definition rolling_audio_capture_buffer.hpp:24
std::uint64_t requested_frames
Definition rolling_audio_capture_buffer.hpp:22
std::uint64_t allocated_frames
Definition rolling_audio_capture_buffer.hpp:23
bool ok
Definition rolling_audio_capture_buffer.hpp:21
Definition rolling_audio_capture_buffer.hpp:27
std::uint64_t start_frame
Definition rolling_audio_capture_buffer.hpp:32
std::uint64_t capacity_frames
Definition rolling_audio_capture_buffer.hpp:31
std::uint64_t generation
Definition rolling_audio_capture_buffer.hpp:29
std::uint64_t end_frame
Definition rolling_audio_capture_buffer.hpp:34
bool valid
Definition rolling_audio_capture_buffer.hpp:28
std::uint64_t frame_count
Definition rolling_audio_capture_buffer.hpp:33
std::uint32_t num_channels
Definition rolling_audio_capture_buffer.hpp:30