mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-10-12 18:38:12 +00:00
[common] ringbuffer: add unbounded mode
In unbounded mode, the read and write pointers are free to move independently of one another. This is useful where the input and output streams are progressing at the same rate on average, and we want to keep the latency stable in the event than an underrun or overrun occurs. If an underrun occurs (i.e., there is not enough data in the buffer to satisfy a read request), the missing values with be filled with zeros. When the writer catches up, the same number of values will be skipped from the input. If an overrun occurs (i.e., there is not enough free space in the buffer to satisfy a write request), excess values will be discarded. When the reader catches up, the same number of values will be zeroed in the output. Unbounded mode is currently unused since our audio input and output streams are not synchronised. This will be implemented in a later commit. Also reimplemented as a lock-free queue which is safer for use in audio device callbacks.
This commit is contained in:

committed by
Geoffrey McRae

parent
b34b253814
commit
599fdd6ffd
@@ -25,9 +25,24 @@ typedef struct RingBuffer * RingBuffer;
|
||||
|
||||
RingBuffer ringbuffer_new(int length, size_t valueSize);
|
||||
|
||||
/* In an unbounded ring buffer, the read and write pointers are free to move
|
||||
* independently of one another. This is useful if your input and output streams
|
||||
* are progressing at the same rate on average, and you want to keep the
|
||||
* latency stable in the event than an underrun or overrun occurs.
|
||||
*
|
||||
* If an underrun occurs (i.e., there is not enough data in the buffer to
|
||||
* satisfy a read request), the missing values with be filled with zeros. When
|
||||
* the writer catches up, the same number of values will be skipped from the
|
||||
* input.
|
||||
*
|
||||
* If an overrun occurs (i.e., there is not enough free space in the buffer to
|
||||
* satisfy a write request), excess values will be discarded. When the reader
|
||||
* catches up, the same number of values will be zeroed in the output.
|
||||
*/
|
||||
RingBuffer ringbuffer_newUnbounded(int length, size_t valueSize);
|
||||
|
||||
void ringbuffer_free(RingBuffer * rb);
|
||||
void ringbuffer_push(RingBuffer rb, const void * value);
|
||||
bool ringbuffer_shift(RingBuffer rb, void * dst);
|
||||
void ringbuffer_reset(RingBuffer rb);
|
||||
|
||||
/* Note that the following functions are NOT thread-safe */
|
||||
@@ -35,23 +50,22 @@ int ringbuffer_getLength(const RingBuffer rb);
|
||||
int ringbuffer_getStart (const RingBuffer rb);
|
||||
int ringbuffer_getCount (const RingBuffer rb);
|
||||
void * ringbuffer_getValues(const RingBuffer rb);
|
||||
void * ringBuffer_getLastValue(const RingBuffer rb);
|
||||
|
||||
/* appends up to count values to the buffer returning the number of values
|
||||
* appended
|
||||
/* Appends up to count values to the buffer returning the number of values
|
||||
* appended. If the buffer is unbounded, the return value is always count;
|
||||
* excess values will be discarded if the buffer is full. Pass a null values
|
||||
* pointer to write zeros to the buffer. Count may be negative in unbounded mode
|
||||
* to seek backwards.
|
||||
* Note: This function is thread-safe */
|
||||
int ringbuffer_append(const RingBuffer rb, const void * values, int count);
|
||||
|
||||
/* consumes and returns up to *count values from the buffer setting *count to
|
||||
* the number of valid values returned.
|
||||
/* Consumes up to count values from the buffer returning the number of values
|
||||
* consumed. If the buffer is unbounded, the return value is always count;
|
||||
* excess values will be zeroed if there is not enough data in the buffer. Pass
|
||||
* a null values pointer to move the read pointer without reading any data.
|
||||
* Count may be negative in unbounded mode to seek backwards.
|
||||
* Note: This function is thread-safe */
|
||||
void * ringbuffer_consume(const RingBuffer rb, int * count);
|
||||
|
||||
typedef void (*RingBufferValueFn)(void * value, void * udata);
|
||||
|
||||
// set a function to call before a value is about to be overwritten
|
||||
void ringbuffer_setPreOverwriteFn(RingBuffer rb, RingBufferValueFn fn,
|
||||
void * udata);
|
||||
int ringbuffer_consume(const RingBuffer rb, void * values, int count);
|
||||
|
||||
typedef bool (*RingBufferIterator)(int index, void * value, void * udata);
|
||||
void ringbuffer_forEach(const RingBuffer rb, RingBufferIterator fn,
|
||||
|
Reference in New Issue
Block a user