rhino/demo/c/pvrecorder/src/pv_circular_buffer.c
Go to the documentation of this file.
1 /*
2  Copyright 2021 Picovoice Inc.
3 
4  You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE"
5  file accompanying this source.
6 
7  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8  an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9  specific language governing permissions and limitations under the License.
10 */
11 
12 #include <stdlib.h>
13 #include <string.h>
14 
15 #include "pv_circular_buffer.h"
16 
17 struct pv_circular_buffer {
18  void *buffer;
19  int32_t capacity;
20  int32_t count;
21  int32_t element_size;
22  int32_t read_index;
23  int32_t write_index;
24 };
25 
27  int32_t capacity,
28  int32_t element_size,
29  pv_circular_buffer_t **object) {
30  if (capacity <= 0) {
32  }
33  if (element_size <= 0) {
35  }
36  if (!object) {
38  }
39 
40  *object = NULL;
41 
42  pv_circular_buffer_t *o = calloc(1, sizeof(pv_circular_buffer_t));
43  if (!o) {
45  }
46 
47  o->buffer = malloc(capacity * element_size);
48  if (!(o->buffer)) {
51  }
52 
53  o->capacity = capacity;
54  o->element_size = element_size;
55 
56  *object = o;
57 
59 }
60 
62  if (object) {
63  free(object->buffer);
64  free(object);
65  }
66 }
67 
68 int32_t pv_circular_buffer_read(pv_circular_buffer_t *object, void *buffer, int32_t length) {
69  if (!object) {
71  }
72  if (!buffer) {
74  }
75  if (!length) {
77  }
78  if ((length <= 0) || (length >= object->capacity)) {
80  }
81 
82  void *dst_ptr = buffer;
83  const void *src_ptr = (char *) object->buffer + (object->read_index * object->element_size);
84 
85  const int32_t available = object->capacity - object->read_index;
86  const int32_t max_copy = (object->count < length) ? object->count : length;
87  const int32_t to_copy = (max_copy < available) ? max_copy : available;
88 
89  memcpy(dst_ptr, src_ptr, to_copy * object->element_size);
90 
91  object->read_index = (object->read_index + to_copy) % object->capacity;
92 
93  const int32_t remaining = max_copy - to_copy;
94  if (remaining > 0) {
95  dst_ptr = (char *) buffer + (to_copy * object->element_size);
96  src_ptr = object->buffer;
97 
98  memcpy(dst_ptr, src_ptr, remaining * object->element_size);
99 
100  object->read_index = remaining;
101  }
102 
103  object->count -= max_copy;
104 
105  return max_copy;
106 }
107 
108 pv_circular_buffer_status_t pv_circular_buffer_write(pv_circular_buffer_t *object, const void *buffer, int32_t length) {
109  if (!object) {
111  }
112  if (!buffer) {
114  }
115  if ((length <= 0) || (length >= object->capacity)) {
117  }
118 
120 
121  void *dst_ptr = (char *) object->buffer + (object->write_index * object->element_size);
122  const void *src_ptr = buffer;
123 
124  const int32_t available = object->capacity - object->write_index;
125  const int32_t to_copy = (length < available) ? length : available;
126 
127  memcpy(dst_ptr, src_ptr, to_copy * object->element_size);
128 
129  object->write_index = (object->write_index + to_copy) % object->capacity;
130  object->count += to_copy;
131 
132  const int32_t remaining = length - to_copy;
133  if (remaining > 0) {
134  dst_ptr = object->buffer;
135  src_ptr = (char *) buffer + (to_copy * object->element_size);
136 
137  memcpy(dst_ptr, src_ptr, remaining * object->element_size);
138 
139  object->write_index = remaining;
140  object->count += remaining;
141  }
142 
143  if(object->count > object->capacity) {
145  object->count = object->capacity;
146  object->read_index = (object->write_index + 1) % object->capacity;
147  }
148 
149  return status;
150 }
151 
153  object->count = 0;
154  object->read_index = 0;
155  object->write_index = 0;
156 }
157 
159  static const char *const STRINGS[] = {
160  "SUCCESS",
161  "OUT_OF_MEMORY",
162  "INVALID_ARGUMENT",
163  "WRITE_OVERFLOW"};
164 
165  int32_t size = sizeof(STRINGS) / sizeof(STRINGS[0]);
166  if (status < PV_CIRCULAR_BUFFER_STATUS_SUCCESS || status >= (PV_CIRCULAR_BUFFER_STATUS_SUCCESS + size)) {
167  return NULL;
168  }
169 
170  return STRINGS[status - PV_CIRCULAR_BUFFER_STATUS_SUCCESS];
171 }
pv_circular_buffer_reset
void pv_circular_buffer_reset(pv_circular_buffer_t *object)
Definition: rhino/demo/c/pvrecorder/src/pv_circular_buffer.c:152
PV_CIRCULAR_BUFFER_STATUS_WRITE_OVERFLOW
@ PV_CIRCULAR_BUFFER_STATUS_WRITE_OVERFLOW
Definition: porcupine/demo/c/pvrecorder/include/pv_circular_buffer.h:30
pv_circular_buffer_write
pv_circular_buffer_status_t pv_circular_buffer_write(pv_circular_buffer_t *object, const void *buffer, int32_t length)
Definition: rhino/demo/c/pvrecorder/src/pv_circular_buffer.c:108
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
pv_circular_buffer_init
pv_circular_buffer_status_t pv_circular_buffer_init(int32_t capacity, int32_t element_size, pv_circular_buffer_t **object)
Definition: rhino/demo/c/pvrecorder/src/pv_circular_buffer.c:26
pv_circular_buffer_status_t
pv_circular_buffer_status_t
Definition: porcupine/demo/c/pvrecorder/include/pv_circular_buffer.h:26
pv_circular_buffer_status_to_string
const char * pv_circular_buffer_status_to_string(pv_circular_buffer_status_t status)
Definition: rhino/demo/c/pvrecorder/src/pv_circular_buffer.c:158
pv_circular_buffer_read
int32_t pv_circular_buffer_read(pv_circular_buffer_t *object, void *buffer, int32_t length)
Definition: rhino/demo/c/pvrecorder/src/pv_circular_buffer.c:68
pv_circular_buffer::read_index
int32_t read_index
Definition: porcupine/demo/c/pvrecorder/src/pv_circular_buffer.c:22
PV_CIRCULAR_BUFFER_STATUS_SUCCESS
@ PV_CIRCULAR_BUFFER_STATUS_SUCCESS
Definition: porcupine/demo/c/pvrecorder/include/pv_circular_buffer.h:27
PV_CIRCULAR_BUFFER_STATUS_INVALID_ARGUMENT
@ PV_CIRCULAR_BUFFER_STATUS_INVALID_ARGUMENT
Definition: porcupine/demo/c/pvrecorder/include/pv_circular_buffer.h:29
PV_CIRCULAR_BUFFER_STATUS_OUT_OF_MEMORY
@ PV_CIRCULAR_BUFFER_STATUS_OUT_OF_MEMORY
Definition: porcupine/demo/c/pvrecorder/include/pv_circular_buffer.h:28
pv_circular_buffer_delete
void pv_circular_buffer_delete(pv_circular_buffer_t *object)
Definition: rhino/demo/c/pvrecorder/src/pv_circular_buffer.c:61
pv_circular_buffer
Definition: porcupine/demo/c/pvrecorder/src/pv_circular_buffer.c:17
pv_circular_buffer::element_size
int32_t element_size
Definition: porcupine/demo/c/pvrecorder/src/pv_circular_buffer.c:21
pv_circular_buffer::buffer
void * buffer
Definition: porcupine/demo/c/pvrecorder/src/pv_circular_buffer.c:18
pv_circular_buffer::write_index
int32_t write_index
Definition: porcupine/demo/c/pvrecorder/src/pv_circular_buffer.c:23
pv_circular_buffer::capacity
int32_t capacity
Definition: porcupine/demo/c/pvrecorder/src/pv_circular_buffer.c:19
pv_circular_buffer::count
int32_t count
Definition: porcupine/demo/c/pvrecorder/src/pv_circular_buffer.c:20


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:14:50