|
| | MidiBuffer ()=default |
| | MidiBuffer (const MidiBuffer &other) |
| MidiBuffer & | operator= (const MidiBuffer &other) |
| | MidiBuffer (MidiBuffer &&other) noexcept |
| MidiBuffer & | operator= (MidiBuffer &&other) noexcept |
| bool | add (const MidiEvent &event) |
| | Append a MIDI event to the buffer.
|
| bool | add (MidiEvent &&event) |
| | Append a MIDI event to the buffer.
|
| void | clear () |
| | Remove all events.
|
| bool | empty () const |
| std::size_t | size () const |
| void | reserve_events (std::size_t capacity) |
| void | reserve_sysex (std::size_t capacity) |
| void | reserve (std::size_t event_capacity, std::size_t sysex_capacity=0, std::size_t sysex_copy_payload_capacity=0) |
| | Preallocate storage for realtime callers that append during process().
|
| void | set_realtime_capacity_limit (bool enabled=true) |
| | When enabled, add() and move-based add_sysex() drop once reserved capacity is full instead of growing vectors.
|
| bool | realtime_capacity_limited () const |
| std::size_t | event_capacity () const |
| std::size_t | sysex_capacity () const |
| std::size_t | sysex_copy_payload_capacity () const |
| std::uint32_t | dropped_event_count () const |
| std::uint32_t | dropped_sysex_count () const |
| void | sort () |
| | Sort events by sample_offset for sample-accurate processing.
|
| auto | begin () |
| auto | end () |
| auto | begin () const |
| auto | end () const |
| const MidiEvent & | operator[] (std::size_t index) const |
| void | attach_ump (class UmpBuffer *ump) |
| | Attach a UmpBuffer sidecar carrying MIDI 2.0 packets that can't be represented as choc::midi::ShortMessage (UMP type-4 channel voice, type-3/5 data, type-0 utility, etc.).
|
| const class UmpBuffer * | ump () const |
| | Attached UmpBuffer or nullptr.
|
| class UmpBuffer * | ump () |
| bool | add_sysex (std::vector< uint8_t > data, int32_t sample_offset=0, double ts=0.0) |
| bool | add_sysex (SysexEvent &&event) |
| bool | add_sysex_copy (const uint8_t *data, std::size_t size, int32_t sample_offset=0, double ts=0.0) |
| void | reserve_sysex_copy_payloads (std::size_t payload_count, std::size_t payload_capacity) |
| void | clear_sysex () |
| std::size_t | sysex_size () const |
| const std::vector< SysexEvent > & | sysex () const |
| std::vector< SysexEvent > & | sysex () |
Collection of timestamped MIDI events within a single audio buffer period.
Events are appended via add() and should be sorted by sample_offset (call sort()) before iterating in the audio callback. Supports range-based for loops.
Realtime contract: the buffer is safe for audio-thread appends only after the owner has called reserve() with the worst-case block capacities and set_realtime_capacity_limit(true). In that mode add() and SysEx append helpers drop and count overflow instead of growing storage. Without that preparation, vector growth remains possible and callers must treat mutation as control/offline-thread work.
for (const auto& ev : buf) { }
void sort()
Sort events by sample_offset for sample-accurate processing.
Definition buffer.hpp:177
bool add(const MidiEvent &event)
Append a MIDI event to the buffer.
Definition buffer.hpp:98
static MidiEvent note_on(uint8_t channel, uint8_t note, uint8_t velocity)
Create a Note On event.
Definition message.hpp:46
| void pulp::midi::MidiBuffer::sort |
( |
| ) |
|
|
inline |
Sort events by sample_offset for sample-accurate processing.
Call this before iterating in the audio callback. Realtime callers must not append while sorting and should rely on adapters to have bounded the event count before process().
The sort is insertion-stable: events at the same sample offset keep the relative order in which they were add()'ed (a controller appended before a note-on at the same offset stays before it). This preserves the same-offset musical semantics every consumer had, while remaining deterministic run-to-run. Implemented as an index sort with a pre-reserved scratch (an std::sort over indices keyed by (sample_offset, original_index) — a valid strict-weak total order — then a one-pass reorder through the scratch), NOT std::stable_sort (which may allocate a temporary buffer). The comparator never touches variable-length sysex payload bytes. Allocation-free when the scratch was reserved (reserve()/reserve_events() size it to the event capacity); only an unreserved, growing buffer can allocate here.