TPCircularBuffer

repository·master·Indexed 21 days ago

https://github.com/michaeltyson/tpcircularbuffer

A high-performance C implementation of a circular (ring) buffer optimized for audio processing. It utilizes a virtual memory mapping technique to eliminate manual buffer wrapping logic and is thread-safe under a Single Producer / Single Consumer (SPSC) model using OSAtomic.h primitives. Includes helper functions for Core Audio AudioBufferList structures.

Tokens
737
Snippets
3
Records
5
Agent score
25%

What's inside tpcircularbuffer

  1. Thread safety requirements for TPCircularBuffer

    master

    The TPCircularBuffer is thread-safe under a Single Producer / Single Consumer (SPSC) model.

    To maintain thread safety:

    • Ensure only one thread is producing data.
    • Ensure only one thread is consuming data.

    The implementation uses OSAtomic.h primitives to atomically update the buffer fill count, which is the only shared variable between the producer and consumer.

  2. Initialize and clean up a TPCircularBuffer

    master

    To use the circular buffer, you must first allocate its resources and ensure they are freed when they are no longer needed. Use TPCircularBufferInit for allocation and TPCircularBufferCleanup for deallocation.

    // Initialization
    TPCircularBuffer *buffer = TPCircularBufferInit(capacity);
    
    // ... use buffer ...
    
    // Cleanup
    TPCircularBufferCleanup(buffer);
  3. Use TPCircularBuffer with AudioBufferList

    master
    The library provides helper functions via TPCircularBuffer+AudioBufferList.(c,h) to simplify working with Core Audio AudioBufferList structures. These helpers automatically queue and dequeue AudioBufferList objects and ensure that the mData fields of each buffer point to 16-byte aligned regions within the circular buffer.
  4. Produce data to the circular buffer

    master

    Data can be added to the buffer using two primary methods:

    1. Manual Pointer Access: Use TPCircularBufferHead to obtain a pointer to the current write position, write your data to that pointer, and then call TPCircularBufferProduce to commit the written bytes.
    2. Convenience Routine: Use TPCircularBufferProduceBytes to write data directly to the buffer in a single step.

    Note: This implementation uses a virtual memory mapping technique to avoid buffer wrapping logic, meaning you can write linearly into the buffer.

    // Method 1: Manual pointer access
    void *head = TPCircularBufferHead(buffer);
    // ... write data to head ...
    TPCircularBufferProduce(buffer, bytesWritten);
    
    // Method 2: Convenience routine
    TPCircularBufferProduceBytes(buffer, dataPointer, bytesToProduce);
  5. Consume data from the circular buffer

    master

    To read data from the buffer, follow these steps:

    1. Use TPCircularBufferTail to get a pointer to the next available data to read.
    2. Process the data at that pointer.
    3. Call TPCircularBufferConsume to advance the tail and free up the space in the buffer once processing is complete.
    // 1. Get pointer to data
    void *tail = TPCircularBufferTail(buffer);
    // ... process data at tail ...
    
    // 2. Free up space
    TPCircularBufferConsume(buffer, bytesConsumed);