source: src/utils/ringbuffer.c @ a6356d4

sampler
Last change on this file since a6356d4 was a6356d4, checked in by Paul Brossier <piem@piem.org>, 7 years ago

src/utils/ringbuffer.c: avoid declaration after statement [msvc]

  • Property mode set to 100644
File size: 5.5 KB
Line 
1
2
3#include "aubio_priv.h"
4#include "fvec.h"
5#include "utils/ringbuffer.h"
6#include <assert.h>
7
8struct _aubio_ringbuffer_t
9{
10  uint_t maxwrite;
11  uint_t maxrequest;
12  fvec_t *buffer;
13  uint_t write_pos;
14  uint_t read_pos;
15  sint_t available;
16};
17
18aubio_ringbuffer_t * new_aubio_ringbuffer(uint_t maxwrite, uint_t maxrequest)
19{
20  aubio_ringbuffer_t *p = AUBIO_NEW (aubio_ringbuffer_t);
21  p->maxwrite = maxwrite;
22  p->maxrequest = maxrequest;
23  //p->buffer = new_fvec(MAX(maxwrite, maxrequest));
24  p->buffer = new_fvec(maxwrite + maxrequest);
25  p->write_pos = p->read_pos = p->available = 0;
26  return p;
27}
28
29uint_t aubio_ringbuffer_push(aubio_ringbuffer_t *o, fvec_t *input, uint_t write) {
30  if ((sint_t)o->buffer->length < o->available + (sint_t)write) {
31    AUBIO_ERR("ringbuffer: push: writing %d but capacity is %d and %d are available\n",
32        write, o->buffer->length, o->available);
33    return AUBIO_FAIL;
34  }
35  if (write > o->maxwrite) {
36    AUBIO_ERR("ringbuffer: push: trying to write %d but maxwrite is %d\n",
37        write, o->maxwrite);
38    return AUBIO_FAIL;
39  } else
40  if (write > input->length) {
41    AUBIO_ERR("ringbuffer: push: trying to write %d, but input vector is %d long\n",
42        write, input->length);
43    return AUBIO_FAIL;
44  } else
45  if (o->write_pos + write <= o->buffer->length) {
46    // write everything at once
47    fvec_t tmp, tmpin;
48    tmp.data = o->buffer->data + o->write_pos; tmp.length = write;
49    tmpin.data = input->data; tmpin.length = write;
50    //assert(tmpin.length == tmp.length);
51    fvec_copy(&tmpin, &tmp);
52
53    //AUBIO_WRN("ringbuffer: push1: changing write_pos from %d\n", o->write_pos);
54    o->write_pos = (o->write_pos % o->buffer->length);
55    o->write_pos += write;
56    o->available += write;
57    //AUBIO_WRN("ringbuffer: push1: changed write_pos to %d\n", o->write_pos);
58
59    //AUBIO_WRN("ringbuffer: push1: wrote %d, %d available\n", write,
60    //    o->available);
61
62    return AUBIO_OK;
63  } else {
64    // write in two folds
65    uint_t remaining = o->buffer->length - o->write_pos;
66    fvec_t tmp, tmpin;
67    // write end
68    if (remaining) {
69      tmp.data = o->buffer->data + o->write_pos;
70      tmp.length = remaining;
71      tmpin.data = input->data;
72      tmpin.length = remaining;
73      //assert(tmpin.length == tmp.length);
74      fvec_copy(&tmpin, &tmp);
75    }
76    // write start
77    tmp.data = o->buffer->data;
78    tmp.length = write - remaining;
79    tmpin.data = input->data + remaining;
80    tmpin.length = write - remaining;
81    //assert(tmpin.length == tmp.length);
82    fvec_copy(&tmpin, &tmp);
83    //AUBIO_WRN("ringbuffer: push2: changing write_pos from %d\n", o->write_pos);
84    o->write_pos += write;
85    o->write_pos = (o->write_pos % o->buffer->length);
86    o->available += write;
87    //AUBIO_WRN("ringbuffer: push2: changed write_pos to %d\n", o->write_pos);
88
89    //AUBIO_WRN("ringbuffer: push2: wrote %d, %d available\n", write,
90    //    o->available);
91
92    return AUBIO_OK;
93  }
94}
95
96uint_t aubio_ringbuffer_pull(aubio_ringbuffer_t *o, fvec_t *output, uint_t request) {
97  if (o->available < (sint_t)request) {
98    AUBIO_ERR("ringbuffer: pull: requested %d but %d available\n",
99        request, o->available);
100    return AUBIO_FAIL;
101  }
102  if (request > o->maxrequest) {
103    AUBIO_ERR("ringbuffer: pull: trying to request %d but maxrequest is %d\n",
104        request, o->maxrequest);
105    return AUBIO_FAIL;
106  } else
107  if (request > output->length) {
108    AUBIO_ERR("ringbuffer: pull: trying to request %d, but output vector is %d long\n",
109        request, output->length);
110    return AUBIO_FAIL;
111  } else
112  if (o->read_pos + request <= o->buffer->length) {
113    // read everything at once
114    fvec_t tmp, tmpout;
115    tmp.data = o->buffer->data + o->read_pos; tmp.length = request;
116    tmpout.data = output->data; tmpout.length = request;
117    //assert(tmpout.length == tmp.length);
118    fvec_copy(&tmp, &tmpout);
119    //AUBIO_WRN("ringbuffer: pull1: changing read_pos from %d\n", o->read_pos);
120    o->read_pos += request;
121    o->read_pos %= o->buffer->length;
122    o->available -= request;
123    //AUBIO_WRN("ringbuffer: pull1: read %d, %d available\n", request,
124    //    o->available);
125    //AUBIO_WRN("ringbuffer: pull1: changed read_pos to %d\n", o->read_pos);
126    return AUBIO_OK;
127  } else {
128    // read in two folds
129    uint_t remaining = o->buffer->length - o->read_pos;
130    fvec_t tmp, tmpout;
131    tmp.data = o->buffer->data + o->read_pos;
132    tmp.length = remaining;
133    tmpout.data = output->data;
134    tmpout.length = remaining;
135    //assert(tmpout.length == tmp.length);
136    fvec_copy(&tmpout, &tmp);
137    // write start
138    tmp.data = o->buffer->data;
139    tmp.length = request - remaining;
140    tmpout.data = output->data + remaining;
141    tmpout.length = request - remaining;
142    //assert(tmpout.length == tmp.length);
143    fvec_copy(&tmp, &tmpout);
144    //AUBIO_WRN("ringbuffer: pull2: changing read_pos from %d\n", o->read_pos);
145    o->read_pos += request;
146    o->read_pos %= o->buffer->length;
147    o->available -= request;
148    //AUBIO_WRN("ringbuffer: pull2: changed read_pos to %d\n", o->read_pos);
149    //AUBIO_WRN("ringbuffer: pull2: read %d, %d available\n", request,
150    //    o->available);
151    return AUBIO_OK;
152  }
153}
154
155uint_t aubio_ringbuffer_reset(aubio_ringbuffer_t *o) {
156  o->read_pos = o->write_pos = 0;
157  o->available = 0;
158  return AUBIO_OK;
159}
160
161sint_t aubio_ringbuffer_get_available(aubio_ringbuffer_t *o) {
162  //AUBIO_WRN("ringbuffer: got %d available (%d ... %d)\n",
163  //    o->available, o->read_pos, o->write_pos);
164  return o->available;
165}
166
167void del_aubio_ringbuffer(aubio_ringbuffer_t *o) {
168  del_fvec(o->buffer);
169  AUBIO_FREE(o);
170}
Note: See TracBrowser for help on using the repository browser.