Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_data_stream.c
1 #include <bc_data_stream.h>
2 
3 static int _bc_data_stream_compare_float(const void * a, const void * b);
4 static int _bc_data_stream_compare_int(const void * a, const void * b);
5 //
6 void bc_data_stream_init(bc_data_stream_t *self, int min_number_of_samples, bc_data_stream_buffer_t *buffer)
7 {
8  memset(self, 0, sizeof(*self));
9  self->_buffer = buffer;
10  self->_counter = 0;
11  self->_feed_head = self->_buffer->number_of_samples - 1;
12  self->_min_number_of_samples = min_number_of_samples;
13 }
14 
15 void bc_data_stream_feed(bc_data_stream_t *self, void *data)
16 {
17  if (data == NULL)
18  {
20  return;
21  }
22 
23  if (++self->_feed_head == self->_buffer->number_of_samples)
24  {
25  self->_feed_head = 0;
26  }
27 
28  switch (self->_buffer->type)
29  {
30  case BC_DATA_STREAM_TYPE_FLOAT:
31  {
32  if (isnan(*(float *) data) || isinf(*(float *) data))
33  {
35 
36  return;
37  }
38 
39  *((float *) self->_buffer->feed + self->_feed_head) = *(float *) data;
40 
41  break;
42  }
43  case BC_DATA_STREAM_TYPE_INT:
44  {
45  *((int *) self->_buffer->feed + self->_feed_head) = *(int *) data;
46 
47  break;
48  }
49  default:
50  {
51  break;
52  }
53  }
54 
55  self->_counter++;
56 }
57 
59 {
60  self->_counter = 0;
61  self->_feed_head = self->_buffer->number_of_samples - 1;
62 }
63 
65 {
66  return self->_counter;
67 }
68 
70 {
71  return self->_counter > self->_buffer->number_of_samples ? self->_buffer->number_of_samples : self->_counter;
72 }
73 
75 {
76  return self->_buffer->type;
77 }
78 
80 {
81  return self->_buffer->number_of_samples;
82 }
83 
85 {
86  if (self->_counter < self->_min_number_of_samples)
87  {
88  return false;
89  }
90 
91  int length = self->_counter > self->_buffer->number_of_samples ? self->_buffer->number_of_samples : self->_counter;
92 
93  switch (self->_buffer->type)
94  {
95  case BC_DATA_STREAM_TYPE_FLOAT:
96  {
97  float sum = 0;
98  float *buffer = (float *) self->_buffer->feed;
99 
100 
101  for (int i = 0; i < length; i ++)
102  {
103  sum += buffer[i];
104  }
105 
106  *(float *) result = sum / length;
107  break;
108  }
109  case BC_DATA_STREAM_TYPE_INT:
110  {
111  int64_t sum = 0;
112  int *buffer = (int *) self->_buffer->feed;
113 
114  for (int i = 0; i < length; i ++)
115  {
116  sum += buffer[i];
117  }
118 
119  *(int *) result = sum / length;
120  break;
121  }
122  default:
123  {
124  return false;
125  }
126  }
127 
128  return true;
129 }
130 
132 {
133  if (self->_counter < self->_min_number_of_samples)
134  {
135  return false;
136  }
137 
138  int length = self->_counter > self->_buffer->number_of_samples ? self->_buffer->number_of_samples : self->_counter;
139 
140  switch (self->_buffer->type)
141  {
142  case BC_DATA_STREAM_TYPE_FLOAT:
143  {
144  memcpy(self->_buffer->sort, self->_buffer->feed, length * sizeof(float));
145  qsort(self->_buffer->sort, length, sizeof(float), _bc_data_stream_compare_float);
146 
147  float *buffer = (float *) self->_buffer->sort;
148 
149  if (length % 2 == 0)
150  {
151  *(float *) result = (buffer[(length - 2) / 2] + buffer[length / 2]) / 2;
152  }
153  else
154  {
155  *(float *) result = buffer[(length - 1) / 2];
156  }
157  break;
158  }
159  case BC_DATA_STREAM_TYPE_INT:
160  {
161  memcpy(self->_buffer->sort, self->_buffer->feed, length * sizeof(int));
162  qsort(self->_buffer->sort, length, sizeof(int), _bc_data_stream_compare_int);
163 
164  int *buffer = (int *) self->_buffer->sort;
165 
166  if (length % 2 == 0)
167  {
168  *(int *) result = (buffer[(length - 2) / 2] + buffer[length / 2]) / 2;
169  }
170  else
171  {
172  *(int *) result = buffer[(length - 1) / 2];
173  }
174  break;
175  }
176  default:
177  {
178  return false;
179  }
180  }
181 
182  return true;
183 }
184 
186 {
187  if (self->_counter == 0)
188  {
189  return false;
190  }
191 
192  int position = self->_counter < self->_buffer->number_of_samples ? 0 : self->_feed_head + 1;
193 
194  if (position == self->_buffer->number_of_samples)
195  {
196  position = 0;
197  }
198 
199  switch (self->_buffer->type)
200  {
201  case BC_DATA_STREAM_TYPE_FLOAT:
202  {
203  *(float *) result = *((float *) self->_buffer->feed + position);
204  break;
205  }
206  case BC_DATA_STREAM_TYPE_INT:
207  {
208  *(int *) result = *((int *) self->_buffer->feed + position);
209  break;
210  }
211  default:
212  {
213  return false;
214  }
215  }
216 
217  return true;
218 }
219 
220 bool bc_data_stream_get_last(bc_data_stream_t *self, void *result)
221 {
222  if (self->_counter == 0)
223  {
224  return false;
225  }
226 
227  switch (self->_buffer->type)
228  {
229  case BC_DATA_STREAM_TYPE_FLOAT:
230  {
231  *(float *) result = *((float *) self->_buffer->feed + self->_feed_head);
232  break;
233  }
234  case BC_DATA_STREAM_TYPE_INT:
235  {
236  *(int *) result = *((int *) self->_buffer->feed + self->_feed_head);
237  break;
238  }
239  default:
240  {
241  return false;
242  }
243  }
244 
245  return true;
246 }
247 
248 bool bc_data_stream_get_nth(bc_data_stream_t *self, int n, void *result)
249 {
250  int position;
251 
252  if (n < 0)
253  {
254  if (self->_counter + n < 0)
255  {
256  return false;
257  }
258 
259  if (self->_buffer->number_of_samples + n < 0)
260  {
261  return false;
262  }
263 
264  position = self->_counter < self->_buffer->number_of_samples ? self->_counter : self->_feed_head + 1 + self->_buffer->number_of_samples;
265  }
266  else
267  {
268  if (self->_counter < n)
269  {
270  return false;
271  }
272 
273  if (self->_buffer->number_of_samples > n)
274  {
275  return false;
276  }
277 
278  position = self->_counter < self->_buffer->number_of_samples ? 0 : self->_feed_head + 1;
279  }
280 
281  position = (position + n) % self->_buffer->number_of_samples;
282 
283  switch (self->_buffer->type)
284  {
285  case BC_DATA_STREAM_TYPE_FLOAT:
286  {
287  *(float *) result = *((float *) self->_buffer->feed + position);
288  break;
289  }
290  case BC_DATA_STREAM_TYPE_INT:
291  {
292  *(int *) result = *((int *) self->_buffer->feed + position);
293  break;
294  }
295  default:
296  {
297  return false;
298  }
299  }
300 
301  return true;
302 }
303 
304 bool bc_data_stream_get_max(bc_data_stream_t *self, void *result)
305 {
306  if (self->_counter < self->_min_number_of_samples)
307  {
308  return false;
309  }
310 
311  int length = bc_data_stream_get_length(self);
312 
313  switch (self->_buffer->type)
314  {
315  case BC_DATA_STREAM_TYPE_FLOAT:
316  {
317  float *buffer = (float *) self->_buffer->feed;
318 
319  float max = buffer[0];
320 
321  for (int i = 1; i < length; i ++)
322  {
323  if (buffer[i] > max)
324  {
325  max = buffer[i];
326  }
327  }
328 
329  *(float *) result = max;
330 
331  break;
332  }
333  case BC_DATA_STREAM_TYPE_INT:
334  {
335  int *buffer = (int *) self->_buffer->feed;
336 
337  int max = buffer[0];
338 
339  for (int i = 1; i < length; i ++)
340  {
341  if (buffer[i] > max)
342  {
343  max = buffer[i];
344  }
345  }
346 
347  *(int *) result = max;
348 
349  break;
350  }
351  default:
352  {
353  return false;
354  }
355  }
356 
357  return true;
358 }
359 
360 bool bc_data_stream_get_min(bc_data_stream_t *self, void *result)
361 {
362  if (self->_counter < self->_min_number_of_samples)
363  {
364  return false;
365  }
366 
367  int length = bc_data_stream_get_length(self);
368 
369  switch (self->_buffer->type)
370  {
371  case BC_DATA_STREAM_TYPE_FLOAT:
372  {
373  float *buffer = (float *) self->_buffer->feed;
374 
375  float min = buffer[0];
376 
377  for (int i = 1; i < length; i ++)
378  {
379  if (buffer[i] < min)
380  {
381  min = buffer[i];
382  }
383  }
384 
385  *(float *) result = min;
386 
387  break;
388  }
389  case BC_DATA_STREAM_TYPE_INT:
390  {
391  int *buffer = (int *) self->_buffer->feed;
392 
393  int min = buffer[0];
394 
395  for (int i = 1; i < length; i ++)
396  {
397  if (buffer[i] < min)
398  {
399  min = buffer[i];
400  }
401  }
402 
403  *(int *) result = min;
404 
405  break;
406  }
407  default:
408  {
409  return false;
410  }
411  }
412 
413  return true;
414 }
415 
416 static int _bc_data_stream_compare_float(const void *a, const void *b)
417 {
418  return *(float *) a - *(float *) b;
419 }
420 
421 static int _bc_data_stream_compare_int(const void *a, const void *b)
422 {
423  return *(int *) a - *(int *) b;
424 }
bool bc_data_stream_get_last(bc_data_stream_t *self, void *result)
Get last value in data stream.
Buffer for data stream.
void bc_data_stream_reset(bc_data_stream_t *self)
Reset data stream.
bool bc_data_stream_get_max(bc_data_stream_t *self, void *result)
Get max value.
bool bc_data_stream_get_median(bc_data_stream_t *self, void *result)
Get median value of data stream.
bool bc_data_stream_get_first(bc_data_stream_t *self, void *result)
Get first value in data stream.
int bc_data_stream_get_number_of_samples(bc_data_stream_t *self)
Get buffer number_of_samples.
bc_data_stream_type_t
Data stream type.
void bc_data_stream_feed(bc_data_stream_t *self, void *data)
Feed data into stream instance.
bool bc_data_stream_get_min(bc_data_stream_t *self, void *result)
Get min value.
bc_data_stream_type_t bc_data_stream_get_type(bc_data_stream_t *self)
Get type.
bool bc_data_stream_get_average(bc_data_stream_t *self, void *result)
Get average value of data stream.
int bc_data_stream_get_length(bc_data_stream_t *self)
Get length.
int bc_data_stream_get_counter(bc_data_stream_t *self)
Get counter.
struct bc_data_stream_t bc_data_stream_t
Data stream instance.
void bc_data_stream_init(bc_data_stream_t *self, int min_number_of_samples, bc_data_stream_buffer_t *buffer)
Initialize data stream instance.
Definition: bc_data_stream.c:6
bool bc_data_stream_get_nth(bc_data_stream_t *self, int n, void *result)
Get nth value in data stream.