feat: add WAV load/save and ring buffer implementation
Co-authored-by: aider (deepseek/deepseek-reasoner) <aider@aider.chat>
This commit is contained in:
69
src/ringbuffer.c
Normal file
69
src/ringbuffer.c
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "ringbuffer.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline size_t load_head(const RingBuf *r) {
|
||||
return atomic_load_explicit(&r->head, memory_order_relaxed);
|
||||
}
|
||||
static inline size_t load_tail(const RingBuf *r) {
|
||||
return atomic_load_explicit(&r->tail, memory_order_relaxed);
|
||||
}
|
||||
static inline void store_head(RingBuf *r, size_t v) {
|
||||
atomic_store_explicit(&r->head, v, memory_order_relaxed);
|
||||
}
|
||||
static inline void store_tail(RingBuf *r, size_t v) {
|
||||
atomic_store_explicit(&r->tail, v, memory_order_relaxed);
|
||||
}
|
||||
|
||||
int ring_init(RingBuf *r, size_t capacity) {
|
||||
r->buf = (float*)malloc(capacity * sizeof(float));
|
||||
if (!r->buf) return -1;
|
||||
r->capacity = capacity;
|
||||
store_head(r, 0);
|
||||
store_tail(r, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ring_destroy(RingBuf *r) {
|
||||
free(r->buf);
|
||||
r->buf = NULL;
|
||||
r->capacity = 0;
|
||||
}
|
||||
|
||||
size_t ring_readable(const RingBuf *r) {
|
||||
size_t h = load_head(r);
|
||||
size_t t = load_tail(r);
|
||||
if (h >= t) return h - t;
|
||||
else return r->capacity - (t - h);
|
||||
}
|
||||
|
||||
size_t ring_writeable(const RingBuf *r) {
|
||||
return r->capacity - 1 - ring_readable(r);
|
||||
}
|
||||
|
||||
size_t ring_write(RingBuf *r, const float *data, size_t count) {
|
||||
size_t avail = ring_writeable(r);
|
||||
if (count > avail) count = avail;
|
||||
if (count == 0) return 0;
|
||||
size_t head = load_head(r);
|
||||
size_t cap = r->capacity;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
r->buf[head] = data[i];
|
||||
head = (head + 1) % cap;
|
||||
}
|
||||
store_head(r, head);
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t ring_read(RingBuf *r, float *data, size_t count) {
|
||||
size_t avail = ring_readable(r);
|
||||
if (count > avail) count = avail;
|
||||
if (count == 0) return 0;
|
||||
size_t tail = load_tail(r);
|
||||
size_t cap = r->capacity;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
data[i] = r->buf[tail];
|
||||
tail = (tail + 1) % cap;
|
||||
}
|
||||
store_tail(r, tail);
|
||||
return count;
|
||||
}
|
||||
Reference in New Issue
Block a user