Class thl::core::RingBuffer#

template<typename T>
class RingBuffer#

Multi-channel ring buffer over an arbitrary element type.

Push semantics are delay-line friendly: pushing into a full channel silently overwrites the oldest sample (the read position advances), so the buffer can be driven continuously as a history/delay line. Popping an empty channel returns a value-initialized element (T{}).

The element type only needs to be copyable and value-initializable; float for audio, integer types for token/index streams, etc.

Index arithmetic wraps with a compare-and-subtract instead of %: the capacity is a runtime value, so a modulo would be a real integer division on every push/pop &#8212; and anira-style consumers push per sample on targets without a hardware divider (armv7l).

Public Functions

RingBuffer() = default#
inline void initialise_with_positions(size_t num_channels, size_t num_samples)#
inline void initialize_with_positions(size_t num_channels, size_t num_samples)#

American-spelling alias (anira-compatible surface).

inline void clear_with_positions()#
inline void push_sample(size_t channel, T sample)#
inline T pop_sample(size_t channel)#
inline void push_block(size_t channel, const T *data, size_t count)#

Push count samples.

Equivalent to count calls of push_sample(), but copies in at most two contiguous chunks. If count exceeds the capacity only the last capacity samples are retained.

inline void pop_block(size_t channel, T *data, size_t count)#

Pop count samples.

Equivalent to count calls of pop_sample(): any samples beyond what is available are value-initialised (T{}).

inline void push_fill(size_t channel, T value, size_t count)#

Push count copies of value.

Equivalent to count calls of push_sample(value) (e.g. priming a latency with silence) without touching the elements one at a time.

inline size_t discard(size_t channel, size_t count)#

Drop up to count unread samples.

Equivalent to count calls of pop_sample() with the results ignored. Returns how many were dropped.

inline void peek_past_block(size_t channel, T *data, size_t count) const#

Copy the count most recently consumed samples (history) into data, oldest first, so data[count - 1] is the sample popped last.

Equivalent to get_past_sample(channel, count - k) for k in [0, count). Like get_past_sample() the range is not checked against the retained history, and a count beyond the capacity wraps the same way.

inline T get_future_sample(size_t channel, size_t offset) const#
inline T get_past_sample(size_t channel, size_t offset) const#
inline size_t get_available_samples(size_t channel) const#
inline size_t get_available_past_samples(size_t channel) const#
inline size_t get_num_channels() const#
inline size_t get_num_samples() const#