source: src/utils/ringbuffer.c @ 218f670

sampler
Last change on this file since 218f670 was 128589e, checked in by Paul Brossier <piem@piem.org>, 8 years ago

src/utils/ringbuffer.c: remove asserts, make sure request < available

  • 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; tmp.data = o->buffer->data + o->write_pos; tmp.length = write;
48    fvec_t tmpin; tmpin.data = input->data; tmpin.length = write;
49    //assert(tmpin.length == tmp.length);
50    fvec_copy(&tmpin, &tmp);
51
52    //AUBIO_WRN("ringbuffer: push1: changing write_pos from %d\n", o->write_pos);
53    o->write_pos = (o->write_pos % o->buffer->length);
54    o->write_pos += write;
55    o->available += write;
56    //AUBIO_WRN("ringbuffer: push1: changed write_pos to %d\n", o->write_pos);
57
58    //AUBIO_WRN("ringbuffer: push1: wrote %d, %d available\n", write,
59    //    o->available);
60
61    return AUBIO_OK;
62  } else {
63    // write in two folds
64    uint_t remaining = o->buffer->length - o->write_pos;
65    fvec_t tmp, tmpin;
66    // write end
67    if (remaining) {
68      tmp.data = o->buffer->data + o->write_pos;
69      tmp.length = remaining;
70      tmpin.data = input->data;
71      tmpin.length = remaining;
72      //assert(tmpin.length == tmp.length);
73      fvec_copy(&tmpin, &tmp);
74    }
75    // write start
76    tmp.data = o->buffer->data;
77    tmp.length = write - remaining;
78    tmpin.data = input->data + remaining;
79    tmpin.length = write - remaining;
80    //assert(tmpin.length == tmp.length);
81    fvec_copy(&tmpin, &tmp);
82    //AUBIO_WRN("ringbuffer: push2: changing write_pos from %d\n", o->write_pos);
83    o->write_pos += write;
84    o->write_pos = (o->write_pos % o->buffer->length);
85    o->available += write;
86    //AUBIO_WRN("ringbuffer: push2: changed write_pos to %d\n", o->write_pos);
87
88    //AUBIO_WRN("ringbuffer: push2: wrote %d, %d available\n", write,
89    //    o->available);
90
91    return AUBIO_OK;
92  }
93}
94
95uint_t aubio_ringbuffer_pull(aubio_ringbuffer_t *o, fvec_t *output, uint_t request) {
96  if (o->available < (sint_t)request) {
97    AUBIO_ERR("ringbuffer: pull: requested %d but %d available\n",
98        request, o->available);
99    return AUBIO_FAIL;
100  }
101  if (request > o->maxrequest) {
102    AUBIO_ERR("ringbuffer: pull: trying to request %d but maxrequest is %d\n",
103        request, o->maxrequest);
104    return AUBIO_FAIL;
105  } else
106  if (request > output->length) {
107    AUBIO_ERR("ringbuffer: pull: trying to request %d, but output vector is %d long\n",
108        request, output->length);
109    return AUBIO_FAIL;
110  } else
111  if (o->read_pos + request <= o->buffer->length) {
112    // read everything at once
113    fvec_t tmp; tmp.data = o->buffer->data + o->read_pos; tmp.length = request;
114    fvec_t tmpout; tmpout.data = output->data; tmpout.length = request;
115    //assert(tmpout.length == tmp.length);
116    fvec_copy(&tmp, &tmpout);
117    //AUBIO_WRN("ringbuffer: pull1: changing read_pos from %d\n", o->read_pos);
118    o->read_pos += request;
119    o->read_pos %= o->buffer->length;
120    o->available -= request;
121    //AUBIO_WRN("ringbuffer: pull1: read %d, %d available\n", request,
122    //    o->available);
123    //AUBIO_WRN("ringbuffer: pull1: changed read_pos to %d\n", o->read_pos);
124    return AUBIO_OK;
125  } else {
126    // read in two folds
127    uint_t remaining = o->buffer->length - o->read_pos;
128    fvec_t tmp, tmpout;
129    tmp.data = o->buffer->data + o->read_pos;
130    tmp.length = remaining;
131    tmpout.data = output->data;
132    tmpout.length = remaining;
133    //assert(tmpout.length == tmp.length);
134    fvec_copy(&tmpout, &tmp);
135    // write start
136    tmp.data = o->buffer->data;
137    tmp.length = request - remaining;
138    tmpout.data = output->data + remaining;
139    tmpout.length = request - remaining;
140    //assert(tmpout.length == tmp.length);
141    fvec_copy(&tmp, &tmpout);
142    //AUBIO_WRN("ringbuffer: pull2: changing read_pos from %d\n", o->read_pos);
143    o->read_pos += request;
144    o->read_pos %= o->buffer->length;
145    o->available -= request;
146    //AUBIO_WRN("ringbuffer: pull2: changed read_pos to %d\n", o->read_pos);
147    //AUBIO_WRN("ringbuffer: pull2: read %d, %d available\n", request,
148    //    o->available);
149    return AUBIO_OK;
150  }
151}
152
153uint_t aubio_ringbuffer_reset(aubio_ringbuffer_t *o) {
154  o->read_pos = o->write_pos = 0;
155  o->available = 0;
156  return AUBIO_OK;
157}
158
159sint_t aubio_ringbuffer_get_available(aubio_ringbuffer_t *o) {
160  //AUBIO_WRN("ringbuffer: got %d available (%d ... %d)\n",
161  //    o->available, o->read_pos, o->write_pos);
162  return o->available;
163}
164
165void del_aubio_ringbuffer(aubio_ringbuffer_t *o) {
166  del_fvec(o->buffer);
167  AUBIO_FREE(o);
168}
Note: See TracBrowser for help on using the repository browser.