summaryrefslogtreecommitdiffstats
path: root/src/bbuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bbuffer.c')
-rw-r--r--src/bbuffer.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/bbuffer.c b/src/bbuffer.c
new file mode 100644
index 0000000..c8cbaa0
--- /dev/null
+++ b/src/bbuffer.c
@@ -0,0 +1,77 @@
+#include <sys/types.h>
+
+#include "bbuffer.h"
+#include "sydney.h"
+#include "malloc.h"
+#include "macro.h"
+
+int sa_bbuffer_init(sa_bbuffer_t *b, unsigned nchannels, size_t sample_size) {
+ sa_assert(b);
+ sa_assert(nchannels > 0);
+ sa_assert(sample_size > 0);
+
+ b->nchannels = nchannels;
+ b->sample_size = sample_size;
+
+ if (!(b->data = sa_new0(void *, nchannels))) {
+ b->size = NULL;
+ return SA_ERROR_OOM;
+ }
+
+ if (!(b->size = sa_new0(size_t, nchannels))) {
+ sa_free(b->data);
+ b->data = NULL;
+ return SA_ERROR_OOM;
+ }
+
+ return SA_SUCCESS;
+}
+
+void sa_bbuffer_done(sa_bbuffer_t *b) {
+ unsigned i;
+ sa_assert(b);
+
+ if (b->data) {
+ for (i = 0; i < b->nchannels; i++)
+ sa_free(b->data[i]);
+
+ sa_free(b->data);
+ }
+
+ sa_free(b->size);
+
+ b->data = NULL;
+ b->size = NULL;
+}
+
+void* sa_bbuffer_get(sa_bbuffer_t *b, unsigned channel, size_t size, int interleave) {
+ sa_assert(b);
+ sa_assert(channel < b->nchannels);
+ sa_assert(size > 0);
+
+ if (interleave) {
+
+ if (!b->data[0] || size * b->nchannels > b->size[0]) {
+ sa_free(b->data[0]);
+ b->size[0] = size * b->nchannels;
+
+ if (!(b->data[0] = sa_malloc(b->size[0])))
+ return NULL;
+ }
+
+ return (uint8_t*) b->data[0] + (b->sample_size * channel);
+
+ } else {
+
+ if (!b->data[channel] || size > b->size[channel]) {
+
+ sa_free(b->data[channel]);
+ b->size[channel] = size;
+
+ if (!(b->data[channel] = sa_malloc(size)))
+ return NULL;
+ }
+
+ return b->data[channel];
+ }
+}