No description
  • C 99.4%
  • Makefile 0.6%
Find a file
Gergely Gati 3616b22be8
Enhance README description of ring buffer utility
Expanded description of the ring buffer utility to include its ability to refill at any time.
2026-02-01 22:34:09 -08:00
.gitignore Initial commit 2025-11-17 20:44:50 -08:00
jfrb.h license added 2025-11-29 07:19:24 -08:00
LICENSE Initial commit 2025-11-17 20:44:50 -08:00
Makefile initial checkin code and test 2025-11-17 21:10:56 -08:00
README.md Enhance README description of ring buffer utility 2026-02-01 22:34:09 -08:00
test.c license added 2025-11-29 07:19:24 -08:00

jfrb

Jitter-Reducing Ring Buffer

Ring buffer utility designed for streaming processors that require predictable chunks of consecutive input data and can refill itself anytime not just when empty.

API Reference

void jfrb_init(struct jfrb_s *rb, uint8_t *buf, uint32_t buflen, jfrb_read_t read, void *ud);

Initializes a ring buffer instance.

  • rb Pointer to a supplied jfrb_s structure.
  • buf Backing storage for the ring buffer.
  • buflen Size of the storage in bytes.
  • read Callback used to read fresh data into the buffer.
  • ud User-defined pointer passed to the read callback.

The buffer starts empty, with all internal state cleared.


uint8_t *jfrb_consume_chunk(struct jfrb_s *rb, uint32_t consumed);

Returns a pointer to the next consecutive region of buffered data and advances the buffer position by consumed bytes.

consumed must be greater than zero and must not exceed the value returned by jfrb_prepare_chunk().

The returned pointer is valid for exactly consumed bytes.


int jfrb_prepare_chunk(struct jfrb_s *rb);

Returns the number of consecutive bytes currently available for consumption without wrapping.

If the current region is empty, this function may trigger a refill or roll the buffer window as needed. It guarantees that the returned size always corresponds to a fully continuous range.

A return value of zero indicates end-of-stream as reported by the read callback.


void jfrb_prefill(struct jfrb_s *rb);

Attempts to refill the unused section(s) of the buffer without disturbing the currently valid data.

Useful for periodically aligning the buffer so that future consume calls get larger consecutive regions, which reduces jitter in downstream processing.


int jfrb_refill(struct jfrb_s *rb);

Performs a full refill of the entire buffer using the read callback.

Resets pos, top, and fill so that the buffer becomes one continuous block of fresh data.

Returns zero on success.


int jfrb_next_chunk(struct jfrb_s *rb, int *have);

Compact combined API to return the pointer to the next consecutive region of buffered data and wrap around the buffer if necessary or refill if empty. The provided have pointer will contain the size of the available data.

The returned pointer is points to exactly have bytes of buffered data.


int jfrb_release_chunk(struct jfrb_s *rb, int size);

Release the obtained buffer received by jfrb_next_chunk() or jfrb_consume_chunk() after using the data of it. The given size should be less or equal than the buffer size received by the API calls. All data in the buffer should be released before requesting more.


Typical Usage Pattern

jfrb_init(&rb, buf, bufsiz, custom_read, NULL);     // initialize state
jfrb_refill(&rb);                                   // fill buffer before processing

int left=total_bytes;
int have;
uint8_t *p;
while((p=jfrb_next_chunk(&rb, &have)) && left>0)      // compact api gives size and pointer
{
    int len=MIN(have, left);                          // if read cb cannot detect EOF it could be too large
    process_chunk(p, len);                            // process the available data
    left-=csm;
    jfrb_release_buffer(rb, len);                     // release the buffer after processing
    if( <time-budget-allows> ) jfrb_prefill(&rb);     // occasional prefill to reduce jitter (frame boundary)
}

This loop continuously requests the next block of consecutive data, processes it, and occasionally performs a prefill to keep future reads jitter free.