Circular Buffer (cbuffer)

circular buffer

The cbuffer object in liquid implements a an efficient first in, first out circular buffer using a minimal amount of memory. Data samples can be easily added to the buffer using the push() and write() methods; invoking the read() method will simply pass a pointer to the buffer's internal contents. The interface for the cbuffer family of objects is listed below. While the interface is given for cbufferf for floating-point precision, equivalent interfaces exist for float complex with cbuffercf .

  • cbufferf_create(n) creates a circular buffer object that can hold up to n samples
  • cbufferf_destroy(q) destroys the circular buffer object q freeing all internal memory
  • cbufferf_print(q) prints properties of the circular buffer object q
  • cbufferf_debug_print(q) prints properties of the circular buffer object q along with its internal state such as the read and write pointer locations and extra memory values.
  • cbufferf_clear(q) clears the internal state of the circular buffer q releasing all values
  • cbufferf_size(q) returns the number of elements currently in the buffer
  • cbufferf_max_size(q) returns the maximum number of elements the buffer can hold
  • cbufferf_read(q,**v,*nr) reads the contents of the circular buffer q , sets the output pointer v to the internal memory state, and sets the value dereferenced by the pointer *nr to the number of read values. See the code listing below for an example.

#include <liquid/liquid.h>

int main() {
    // initialize array for writing
    float v[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};

    // create circular buffer with up to 10 elements
    cbufferf cb = cbufferf_create(10);
    // cbuffer[0] : { <empty> }

    // push 4 elements into the window
    cbufferf_push(cb, 1);
    cbufferf_push(cb, 3);
    cbufferf_push(cb, 6);
    cbufferf_push(cb, 2);
    // cbuffer[4] : {1 3 6 2}

    // write the first 4 values of 'v'
    cbufferf_write(cb, v, 4);
    // cbuffer[8] : {1 3 6 2 9 8 7 6}

    // release the oldest 6 values
    cbufferf_release(cb, 6);
    // cbuffer[2] : {7 6}

    // write 8 values into buffer
    cbufferf_write(cb, v, 8);
    // cbuffer[10] : {7 6 9 8 7 6 5 4 3 2}

    // read buffer (return pointer to aligned memory)
    float * r;
    unsigned int num_requested = 3;
    unsigned int num_read;
    cbufferf_read(cb, num_requested, &r, &num_read);
    printf("cbufferf: requested %u elements, read %u elements\n",
            num_requested, num_read);
    // r[3] : {7 6 9}

    // clean up allocated object
    cbufferf_destroy(cb);

    return 0;
}