• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 /*
12  * Provides a generic ring buffer that can be written to and read from with
13  * arbitrarily sized blocks. The AEC uses this for several different tasks.
14  */
15 
16 #include <stdlib.h>
17 #include <string.h>
18 #include "ring_buffer.h"
19 
20 typedef struct {
21     int readPos;
22     int writePos;
23     int size;
24     char rwWrap;
25     bufdata_t *data;
26 } buf_t;
27 
28 enum {SAME_WRAP, DIFF_WRAP};
29 
WebRtcApm_CreateBuffer(void ** bufInst,int size)30 int WebRtcApm_CreateBuffer(void **bufInst, int size)
31 {
32     buf_t *buf = NULL;
33 
34     if (size < 0) {
35         return -1;
36     }
37 
38     buf = malloc(sizeof(buf_t));
39     *bufInst = buf;
40     if (buf == NULL) {
41         return -1;
42     }
43 
44     buf->data = malloc(size*sizeof(bufdata_t));
45     if (buf->data == NULL) {
46         free(buf);
47         buf = NULL;
48         return -1;
49     }
50 
51     buf->size = size;
52     return 0;
53 }
54 
WebRtcApm_InitBuffer(void * bufInst)55 int WebRtcApm_InitBuffer(void *bufInst)
56 {
57     buf_t *buf = (buf_t*)bufInst;
58 
59     buf->readPos = 0;
60     buf->writePos = 0;
61     buf->rwWrap = SAME_WRAP;
62 
63     // Initialize buffer to zeros
64     memset(buf->data, 0, sizeof(bufdata_t)*buf->size);
65 
66     return 0;
67 }
68 
WebRtcApm_FreeBuffer(void * bufInst)69 int WebRtcApm_FreeBuffer(void *bufInst)
70 {
71     buf_t *buf = (buf_t*)bufInst;
72 
73     if (buf == NULL) {
74         return -1;
75     }
76 
77     free(buf->data);
78     free(buf);
79 
80     return 0;
81 }
82 
WebRtcApm_ReadBuffer(void * bufInst,bufdata_t * data,int size)83 int WebRtcApm_ReadBuffer(void *bufInst, bufdata_t *data, int size)
84 {
85     buf_t *buf = (buf_t*)bufInst;
86     int n = 0, margin = 0;
87 
88     if (size <= 0 || size > buf->size) {
89         return -1;
90     }
91 
92     n = size;
93     if (buf->rwWrap == DIFF_WRAP) {
94         margin = buf->size - buf->readPos;
95         if (n > margin) {
96             buf->rwWrap = SAME_WRAP;
97             memcpy(data, buf->data + buf->readPos,
98                 sizeof(bufdata_t)*margin);
99             buf->readPos = 0;
100             n = size - margin;
101         }
102         else {
103             memcpy(data, buf->data + buf->readPos,
104                 sizeof(bufdata_t)*n);
105             buf->readPos += n;
106             return n;
107         }
108     }
109 
110     if (buf->rwWrap == SAME_WRAP) {
111         margin = buf->writePos - buf->readPos;
112         if (margin > n)
113             margin = n;
114         memcpy(data + size - n, buf->data + buf->readPos,
115             sizeof(bufdata_t)*margin);
116         buf->readPos += margin;
117         n -= margin;
118     }
119 
120     return size - n;
121 }
122 
WebRtcApm_WriteBuffer(void * bufInst,const bufdata_t * data,int size)123 int WebRtcApm_WriteBuffer(void *bufInst, const bufdata_t *data, int size)
124 {
125     buf_t *buf = (buf_t*)bufInst;
126     int n = 0, margin = 0;
127 
128     if (size < 0 || size > buf->size) {
129         return -1;
130     }
131 
132     n = size;
133     if (buf->rwWrap == SAME_WRAP) {
134         margin = buf->size - buf->writePos;
135         if (n > margin) {
136             buf->rwWrap = DIFF_WRAP;
137             memcpy(buf->data + buf->writePos, data,
138                 sizeof(bufdata_t)*margin);
139             buf->writePos = 0;
140             n = size - margin;
141         }
142         else {
143             memcpy(buf->data + buf->writePos, data,
144                 sizeof(bufdata_t)*n);
145             buf->writePos += n;
146             return n;
147         }
148     }
149 
150     if (buf->rwWrap == DIFF_WRAP) {
151         margin = buf->readPos - buf->writePos;
152         if (margin > n)
153             margin = n;
154         memcpy(buf->data + buf->writePos, data + size - n,
155             sizeof(bufdata_t)*margin);
156         buf->writePos += margin;
157         n -= margin;
158     }
159 
160     return size - n;
161 }
162 
WebRtcApm_FlushBuffer(void * bufInst,int size)163 int WebRtcApm_FlushBuffer(void *bufInst, int size)
164 {
165     buf_t *buf = (buf_t*)bufInst;
166     int n = 0, margin = 0;
167 
168     if (size <= 0 || size > buf->size) {
169         return -1;
170     }
171 
172     n = size;
173     if (buf->rwWrap == DIFF_WRAP) {
174         margin = buf->size - buf->readPos;
175         if (n > margin) {
176             buf->rwWrap = SAME_WRAP;
177             buf->readPos = 0;
178             n = size - margin;
179         }
180         else {
181             buf->readPos += n;
182             return n;
183         }
184     }
185 
186     if (buf->rwWrap == SAME_WRAP) {
187         margin = buf->writePos - buf->readPos;
188         if (margin > n)
189             margin = n;
190         buf->readPos += margin;
191         n -= margin;
192     }
193 
194     return size - n;
195 }
196 
WebRtcApm_StuffBuffer(void * bufInst,int size)197 int WebRtcApm_StuffBuffer(void *bufInst, int size)
198 {
199     buf_t *buf = (buf_t*)bufInst;
200     int n = 0, margin = 0;
201 
202     if (size <= 0 || size > buf->size) {
203         return -1;
204     }
205 
206     n = size;
207     if (buf->rwWrap == SAME_WRAP) {
208         margin = buf->readPos;
209         if (n > margin) {
210             buf->rwWrap = DIFF_WRAP;
211             buf->readPos = buf->size - 1;
212             n -= margin + 1;
213         }
214         else {
215             buf->readPos -= n;
216             return n;
217         }
218     }
219 
220     if (buf->rwWrap == DIFF_WRAP) {
221         margin = buf->readPos - buf->writePos;
222         if (margin > n)
223             margin = n;
224         buf->readPos -= margin;
225         n -= margin;
226     }
227 
228     return size - n;
229 }
230 
WebRtcApm_get_buffer_size(const void * bufInst)231 int WebRtcApm_get_buffer_size(const void *bufInst)
232 {
233     const buf_t *buf = (buf_t*)bufInst;
234 
235     if (buf->rwWrap == SAME_WRAP)
236         return buf->writePos - buf->readPos;
237     else
238         return buf->size - buf->readPos + buf->writePos;
239 }
240