60template<std::
size_t Capacity = 256>
70 return queue_.try_push(entry);
92 double block_start_seconds,
93 int block_size_samples,
95 if (block_size_samples <= 0 || sample_rate <= 0.0)
return 0;
96 const double block_duration = block_size_samples / sample_rate;
97 const double block_end_seconds = block_start_seconds + block_duration;
99 std::size_t drained = 0;
102 int sample_offset = 0;
103 if (entry.timestamp_seconds > block_start_seconds) {
104 const double offset_seconds = entry.timestamp_seconds - block_start_seconds;
108 sample_offset =
static_cast<int>(std::lround(offset_seconds * sample_rate));
109 sample_offset = std::clamp(sample_offset, 0, block_size_samples - 1);
111 MidiEvent event{entry.message, sample_offset, entry.timestamp_seconds};
121 for (
auto& slot : pending_) {
122 if (slot.has_value() && slot->timestamp_seconds < block_end_seconds) {
142 while (
auto next = queue_.try_pop()) {
143 const auto& entry = *next;
144 if (entry.timestamp_seconds < block_end_seconds) {
150 if (stash_pending(entry)) {
154 dropped_future_.fetch_add(1, std::memory_order_relaxed);
167 return dropped_future_.load(std::memory_order_relaxed);
174 return queue_.overflow_count();
181 queue_.reset_overflow_count();
188 const auto queue = queue_.telemetry();
190 .queue_size_approx = queue.size_approx,
191 .queue_capacity = queue.capacity,
192 .queue_overflow_count = queue.overflow_count,
193 .pending_size_approx = pending_size_approx(),
205 static constexpr std::size_t
capacity() {
return Capacity; }
217 static constexpr std::size_t kPendingSlots = 64;
223 std::array<std::optional<TimestampedShortMessage>, kPendingSlots> pending_{};
224 std::atomic<std::size_t> dropped_future_{0};
226 std::size_t pending_size_approx()
const {
227 std::size_t count = 0;
228 for (
const auto& slot : pending_) {
229 if (slot.has_value()) ++count;
239 bool stash_pending(
const TimestampedShortMessage& entry) {
240 for (
auto& slot : pending_) {
241 if (!slot.has_value()) {
Collection of timestamped MIDI events within a single audio buffer period.
Definition buffer.hpp:31
bool add(const MidiEvent &event)
Append a MIDI event to the buffer.
Definition buffer.hpp:98
std::size_t size_approx() const
Approximate number of events currently queued (does NOT count the deferred-future entries in the pend...
Definition message_collector.hpp:202
MidiMessageCollector()=default
bool push_now(const MidiEvent &event)
Convenience overload using MidiEvent::timestamp directly.
Definition message_collector.hpp:74
std::size_t dropped_future() const
Number of FUTURE events the consumer dropped because the pending ring was saturated at the moment the...
Definition message_collector.hpp:166
std::size_t drain_into(MidiBuffer &out, double block_start_seconds, int block_size_samples, double sample_rate)
Audio / consumer thread — drain queued events into out at the correct sample offsets within the curre...
Definition message_collector.hpp:91
bool push_now(const MidiEvent &event, double now_seconds)
UI / producer thread — push a MidiEvent timestamped at now_seconds.
Definition message_collector.hpp:68
static constexpr std::size_t pending_capacity()
Compile-time size of the consumer-owned pending ring.
Definition message_collector.hpp:214
static constexpr std::size_t capacity()
Compile-time capacity of the producer queue.
Definition message_collector.hpp:205
std::uint64_t queue_overflow_count() const
Producer-side queue overflow count from failed push_now() attempts.
Definition message_collector.hpp:173
MidiMessageCollectorTelemetry telemetry() const
Cheap snapshot for UI, validation, and inspector polling.
Definition message_collector.hpp:187
void reset_queue_overflow_count()
Reset only the producer queue overflow counter.
Definition message_collector.hpp:180
Definition spsc_queue.hpp:23
@ count
sentinel: number of real capabilities (keep LAST)
Definition canvas_capability.hpp:38
Definition custom_node_events.hpp:26
Timestamped MIDI event combining a choc::midi::ShortMessage with timing info.
Definition message.hpp:32
double timestamp
Absolute time in seconds (for device I/O).
Definition message.hpp:35
Definition message_collector.hpp:51
std::size_t pending_size_approx
Definition message_collector.hpp:55
std::size_t queue_size_approx
Definition message_collector.hpp:52
std::uint64_t queue_overflow_count
Definition message_collector.hpp:54
std::size_t dropped_future
Definition message_collector.hpp:57
std::size_t queue_capacity
Definition message_collector.hpp:53
std::size_t pending_capacity
Definition message_collector.hpp:56
Timestamped MIDI event in the collector queue.
Definition message_collector.hpp:46
choc::midi::ShortMessage message
Definition message_collector.hpp:47
double timestamp_seconds
Definition message_collector.hpp:48