arduino-audio-tools
Loading...
Searching...
No Matches
Buffers.h
Go to the documentation of this file.
1#pragma once
2
3#include "AudioToolsConfig.h"
7
14namespace audio_tools {
15
22template <typename T = uint8_t>
24 public:
25 BaseBuffer() = default;
26 virtual ~BaseBuffer() = default;
27 BaseBuffer(const BaseBuffer&) = default;
28 BaseBuffer &operator=(const BaseBuffer &) = default;
29
31 virtual bool read(T &result) = 0;
32
34 virtual int readArray(T data[], int len) {
35 if (data == nullptr) {
36 LOGE("NPE");
37 return 0;
38 }
39 int lenResult = min(len, available());
40 for (int j = 0; j < lenResult; j++) {
41 read(data[j]);
42 }
43 LOGD("readArray %d -> %d", len, lenResult);
44 return lenResult;
45 }
46
48 virtual int clearArray(int len) {
49 int lenResult = min(len, available());
52 return lenResult;
53 }
54
56 virtual int writeArray(const T data[], int len) {
57 // LOGD("%s: %d", LOG_METHOD, len);
58 // CHECK_MEMORY();
59
60 int result = 0;
61 for (int j = 0; j < len; j++) {
62 if (!write(data[j])) {
63 break;
64 }
65 result = j + 1;
66 }
67 // CHECK_MEMORY();
68 LOGD("writeArray %d -> %d", len, result);
69 return result;
70 }
71
73 virtual int writeArrayOverwrite(const T data[], int len) {
74 int to_delete = len - availableForWrite();
75 if (to_delete > 0) {
77 }
78 return writeArray(data, len);
79 }
80
82 virtual bool peek(T &result) = 0;
83
85 virtual bool isFull() { return availableForWrite() == 0; }
86
87 bool isEmpty() { return available() == 0; }
88
90 virtual bool write(T data) = 0;
91
93 virtual void reset() = 0;
94
96 void clear() { reset(); }
97
100 virtual void flush() {}
101
103 virtual int available() = 0;
104
106 virtual int availableForWrite() = 0;
107
109 virtual T *address() = 0;
110
111 virtual size_t size() = 0;
112
114 virtual float levelPercent() {
115 // prevent div by 0.
116 if (size() == 0) return 0.0f;
117 return 100.0f * static_cast<float>(available()) /
118 static_cast<float>(size());
119 }
120
122 virtual bool resize(size_t bytes) {
123 LOGE("resize not implemented for this buffer");
124 return false;
125 }
126
128 virtual int bufferCountFilled() { return -1; }
129
131 virtual int bufferCountEmpty() { return -1; }
132
133};
134
138template <typename T = uint8_t>
140 public:
141 FrameBuffer(BaseBuffer<T> &buffer) { p_buffer = &buffer; }
143 int readFrames(T data[][2], int len) {
144 LOGD("%s: %d", LOG_METHOD, len);
145 // CHECK_MEMORY();
146 int result = min(len, p_buffer->available());
147 for (int j = 0; j < result; j++) {
148 T sample = 0;
149 p_buffer->read(sample);
150 data[j][0] = sample;
151 data[j][1] = sample;
152 }
153 // CHECK_MEMORY();
154 return result;
155 }
156
157 template <int rows, int channels>
158 int readFrames(T (&data)[rows][channels]) {
159 int lenResult = min(rows, p_buffer->available());
160 for (int j = 0; j < lenResult; j++) {
161 T sample = 0;
162 p_buffer->read(sample);
163 for (int i = 0; i < channels; i++) {
164 // data[j][i] = htons(sample);
165 data[j][i] = sample;
166 }
167 }
168 return lenResult;
169 }
170
171 protected:
173};
174
183template <typename T = uint8_t>
184class SingleBuffer : public BaseBuffer<T> {
185 public:
192 : _allocator(allocator) {
193 buffer.resize(size);
194 reset();
195 }
196
197 SingleBuffer(const SingleBuffer&) = default;
199
204
206 void onExternalBufferRefilled(void *data, int len) {
207 this->owns_buffer = false;
208 this->buffer = (uint8_t *)data;
209 this->current_read_pos = 0;
210 this->current_write_pos = len;
211 }
212
213 int writeArray(const T data[], int len) override {
214 if (size() == 0) resize(len);
215 return BaseBuffer<T>::writeArray(data, len);
216 }
217
218 bool write(T sample) override {
219 bool result = false;
220 if (current_write_pos < buffer.size()) {
221 buffer[current_write_pos++] = sample;
222 result = true;
223 }
224 return result;
225 }
226
227 bool read(T &result) override {
228 bool success = false;
230 result = buffer[current_read_pos++];
231 success = true;
232 }
233 return success;
234 }
235
236 bool peek(T &result) override {
237 bool success = false;
239 result = buffer[current_read_pos];
240 success = true;
241 }
242 return success;
243 }
244
245 int available() override {
246 int result = current_write_pos - current_read_pos;
247 return max(result, 0);
248 }
249
250 int availableForWrite() override { return buffer.size() - current_write_pos; }
251
252 bool isFull() override { return availableForWrite() <= 0; }
253
254 int peekArray(uint8_t *data, int len) {
255 int len_available = available();
256 if (len > len_available) {
257 len = len_available;
258 }
259 memcpy(data, buffer.data() + current_read_pos, len);
260 return len;
261 }
262
264 int clearArray(int len) override {
265 int len_available = available();
266 if (len > available()) {
267 reset();
268 return len_available;
269 }
270 current_read_pos += len;
271 len_available -= len;
272 memmove(buffer.data(), buffer.data() + current_read_pos, len_available * sizeof(T));
275
276 if (is_clear_with_zero) {
277 memset(buffer.data() + current_write_pos, 0,
278 buffer.size() - current_write_pos);
279 }
280
281 return len;
282 }
283
285 void trim() {
286 int av = available();
287 memmove(buffer.data(), buffer.data() + current_read_pos, av * sizeof(T));
290 }
291
293 T *address() override { return buffer.data(); }
294
296 T *data() { return buffer.data() + current_read_pos; }
297
298 void reset() override {
301 if (is_clear_with_zero) {
302 memset(buffer.data(), 0, buffer.size());
303 }
304 }
305
309 size_t result = min(available_size, (size_t)buffer.size());
311 current_write_pos = result;
312 return result;
313 }
314
315 size_t size() override { return buffer.size(); }
316
317 bool resize(size_t size) {
318 if (buffer.size() < size) {
319 TRACED();
320 return buffer.resize(size);
321 }
322 return true;
323 }
324
327
329 void setWritePos(int pos) { current_write_pos = pos; }
330
332 int id = 0;
334 bool active = true;
337
338 protected:
342 bool owns_buffer = true;
343 bool is_clear_with_zero = false;
345};
346
352template <typename T = uint8_t>
353class RingBuffer : public BaseBuffer<T> {
354 public:
355 RingBuffer(int size, Allocator &allocator = DefaultAllocator) : _allocator(allocator) {
356 resize(size);
357 reset();
358 }
359
360 bool read(T &result) override {
361 if (isEmpty()) {
362 return false;
363 }
364
365 result = _aucBuffer[_iTail];
367 _numElems--;
368
369 return true;
370 }
371
372 // peeks the actual entry from the buffer
373 bool peek(T &result) override {
374 if (isEmpty()) {
375 return false;
376 }
377
378 result = _aucBuffer[_iTail];
379 return true;
380 }
381
382 virtual int peekArray(T *data, int n) {
383 if (isEmpty()) return -1;
384 int result = 0;
385 int count = _numElems;
386 int tail = _iTail;
387 for (int j = 0; j < n; j++) {
388 data[j] = _aucBuffer[tail];
389 tail = nextIndex(tail);
390 count--;
391 result++;
392 if (count == 0) break;
393 }
394 return result;
395 }
396
397 // checks if the buffer is full
398 virtual bool isFull() override { return available() == max_size; }
399
400 bool isEmpty() { return available() == 0; }
401
402 // write add an entry to the buffer
403 virtual bool write(T data) override {
404 bool result = false;
405 if (!isFull()) {
406 _aucBuffer[_iHead] = data;
408 _numElems++;
409 result = true;
410 }
411 return result;
412 }
413
414 // clears the buffer
415 virtual void reset() override {
416 _iHead = 0;
417 _iTail = 0;
418 _numElems = 0;
419 }
420
421 // provides the number of entries that are available to read
422 virtual int available() override { return _numElems; }
423
424 // provides the number of entries that are available to write
425 virtual int availableForWrite() override { return (max_size - _numElems); }
426
427 // returns the address of the start of the physical read buffer
428 virtual T *address() override { return _aucBuffer.data(); }
429
430 virtual bool resize(size_t len) {
431 if (max_size != len && len > 0) {
432 LOGI("resize: %d", len);
433 _aucBuffer.resize(len);
434 max_size = len;
435 }
436 return true;
437 }
438
440 virtual size_t size() override { return max_size; }
441
442 protected:
448 int max_size = 0;
449
450 int nextIndex(int index) {
451 if (max_size == 0) return 0;
452 return (uint32_t)(index + 1) % max_size; }
453};
454
463template <class File, typename T>
464class RingBufferFile : public BaseBuffer<T> {
465 public:
468 resize(size);
469 begin(file);
470 }
472 if (p_file) p_file->close();
473 }
474
477 if (bufferFile) {
479 } else {
480 LOGE("file is not valid");
481 }
482 return bufferFile;
483 }
484
486 bool read(T &result) override { return readArray(&result, 1) == 1; }
487
489 int readArray(T data[], int count) override {
490 if (p_file == nullptr) return 0;
491 int read_count = min(count, available());
492
494 if (!file_seek(offset.pos)) return false;
495 int n = file_read(data, offset.len);
496 if (offset.len1 > 0) {
497 file_seek(0);
498 n += file_read(data + offset.len, offset.len1);
499 read_pos = offset.len1;
500 } else {
502 }
503
504 for (int i = 0; i < count; i++) {
505 LOGI("read #%d value %d", offset.pos, (int)data[i]);
506 }
507
509 return read_count;
510 }
511
513 bool peek(T &result) override {
514 if (p_file == nullptr || isEmpty()) {
515 return false;
516 }
517
518 if (!file_seek(read_pos)) return false;
519 size_t count = file_read(&result, 1);
520 return count == 1;
521 }
522
524 int peekArray(T data[], int count) {
525 if (p_file == nullptr) return 0;
526 int read_count = min(count, available());
527
529 if (!file_seek(offset.pos)) return false;
530 int n = file_read(data, offset.len);
531 if (offset.len1 > 0) {
532 file_seek(0);
533 n += file_read(data + offset.len, offset.len1);
534 }
535 assert(n == read_count);
536 return read_count;
537 }
538
540 bool write(T data) override { return writeArray(&data, 1); }
541
543 int writeArray(const T data[], int len) override {
544 if (p_file == nullptr) return 0;
545 for (int i = 0; i < len; i++) {
546 LOGI("write #%d value %d", write_pos, (int)data[i]);
547 }
548
549 int write_count = min(len, availableForWrite());
551
552 if (!file_seek(offset.pos)) return false;
553 int n = file_write(data, offset.len);
554 if (offset.len1 > 0) {
555 file_seek(0);
556 n += file_write(data + offset.len, offset.len1);
557 write_pos = offset.len1;
558 } else {
560 }
562 return write_count;
563 }
564
566 bool isFull() override { return available() == max_size; }
567
568 bool isEmpty() { return available() == 0; }
569
571 void reset() override {
572 write_pos = 0;
573 read_pos = 0;
574 element_count = 0;
575 if (p_file != nullptr) file_seek(0);
576 }
577
579 int available() override { return element_count; }
580
582 int availableForWrite() override { return (max_size - element_count); }
583
585 size_t size() override { return max_size; }
586
588 bool resize(size_t size) {
589 max_size = size;
590 return true;
591 }
592
593 // not supported
594 T *address() override { return nullptr; }
595
596 protected:
597 File *p_file = nullptr;
598 int write_pos = 0;
599 int read_pos = 0;
601 int max_size = 0;
602
603 struct OffsetInfo {
604 int pos = 0; // start pos
605 int len = 0; // length of first part
606 int len1 = 0; // length of second part on overflow
607 };
608
611 OffsetInfo getOffset(int pos, int len) {
612 OffsetInfo result;
613 result.pos = pos;
614 int overflow = (pos + len) - max_size;
615 if (overflow <= 0) {
616 // we can write the complete data
617 result.len = len;
618 result.len1 = 0;
619 } else {
620 // we need to split the data
621 result.len = len - overflow;
622 result.len1 = overflow;
623 }
624 return result;
625 }
626
628 bool file_seek(int pos) {
629 int file_pos = pos * sizeof(T);
630 if (p_file->position() != file_pos) {
631 LOGD("file_seek: %d", pos);
632 if (!p_file->seek(file_pos)) {
633 LOGE("seek %d", file_pos);
634 return false;
635 }
636 }
637 return true;
638 }
639
641 int file_write(const T *data, int count) {
642 LOGD("file_write: %d", count);
643 if (p_file == nullptr) return 0;
644 int to_write_bytes = sizeof(T) * count;
645 int bytes_written = p_file->write((const uint8_t *)data, to_write_bytes);
646 p_file->flush();
647 int elements_written = bytes_written / sizeof(T);
649 LOGE("write: %d -> %d bytes", to_write_bytes, bytes_written);
650 }
651 return elements_written;
652 }
653
655 int file_read(T *result, int count) {
656 LOGD("file_read: %d", count);
657 int read_bytes = count * sizeof(T);
658 int result_bytes = p_file->readBytes((char *)result, read_bytes);
659 int result_count = result_bytes / sizeof(T);
660 if (result_count != count) {
661 LOGE("readBytes: %d -> %d", read_bytes, result_bytes);
662 }
663 return result_count;
664 }
665};
666
674template <typename T = uint8_t>
675class NBuffer : public BaseBuffer<T> {
676 public:
677 NBuffer(int size, int count) { resize(size, count); }
678
679 virtual ~NBuffer() { freeMemory(); }
680
682 bool read(T &result) override {
683 if (available() == 0) return false;
684 return actual_read_buffer->read(result);
685 }
686
690 int readArray(T data[], int len) override {
691 int count = 0;
692 while (count < len) {
693 if (available() == 0) break;
694 actual_read_buffer->read(data[count]);
695 count++;
696 }
697 return count;
698 }
699
701 bool peek(T &result) override {
702 if (available() == 0) return false;
703 return actual_read_buffer->peek(result);
704 }
705
707 bool isFull() { return availableForWrite() == 0; }
708
710 bool write(T data) {
711 bool result = false;
712 if (actual_write_buffer == nullptr) {
714 }
715 if (actual_write_buffer != nullptr) {
716 result = actual_write_buffer->write(data);
717 // if buffer is full move to next available
721 }
722 }
723
724 if (start_time == 0l) {
725 start_time = millis();
726 }
727 if (result) sample_count++;
728
729 return result;
730 }
731
733 int available() {
734 if (actual_read_buffer == nullptr) {
736 }
737 if (actual_read_buffer == nullptr) {
738 return 0;
739 }
740 int result = actual_read_buffer->available();
741 if (result == 0) {
742 // make current read buffer available again
743 resetCurrent();
744 result =
745 (actual_read_buffer == nullptr) ? 0 : actual_read_buffer->available();
746 }
747 return result;
748 }
749
752 if (actual_write_buffer == nullptr) {
754 }
755 // if we used up all buffers - there is nothing available any more
756 if (actual_write_buffer == nullptr) {
757 return 0;
758 }
759 // check on actual buffer
761 // if buffer is full we move it to filled buffers ang get the next
762 // available
765 }
767 }
768
772 void flush() {
773 if (actual_write_buffer != nullptr && actual_write_buffer->available() > 0) {
775 actual_write_buffer = nullptr;
776 }
777 }
778
780 void reset() {
781 TRACED();
782 while (actual_read_buffer != nullptr) {
785 // get next read buffer
787 }
788 }
789
791 unsigned long sampleRate() {
792 unsigned long run_time = (millis() - start_time);
793 return run_time == 0 ? 0 : sample_count * 1000 / run_time;
794 }
795
798 return actual_read_buffer == nullptr ? nullptr
800 }
801
803 virtual int bufferCountFilled() { return filled_buffers.size(); }
804
806 virtual int bufferCountEmpty() { return available_buffers.size(); }
807
808 virtual bool resize(size_t bytes) {
809 int count = bytes / buffer_size;
810 return resize(buffer_size, count);
811 }
812
814 virtual bool resize(size_t size, int count) {
815 if (buffer_size == size && buffer_count == count) return true;
816 freeMemory();
817 filled_buffers.resize(count);
818 available_buffers.resize(count);
819 // filled_buffers.clear();
820 // available_buffers.clear();
821
822 buffer_count = count;
824 for (int j = 0; j < count; j++) {
825 BaseBuffer<T> *buffer = new SingleBuffer<T>(size);
826 LOGD("new buffer %p", buffer);
827 available_buffers.enqueue(buffer);
828 }
829 return true;
830 }
831
833 size_t size() { return buffer_size * buffer_count; }
834
835 protected:
836 int buffer_size = 1024;
842 unsigned long start_time = 0;
843 unsigned long sample_count = 0;
844
846 NBuffer() = default;
847
848 void freeMemory() {
850 LOGD("deleting %p", actual_write_buffer);
851 delete actual_write_buffer;
852 actual_write_buffer = nullptr;
853 }
854 if (actual_read_buffer) {
855 LOGD("deleting %p", actual_read_buffer);
856 delete actual_read_buffer;
857 actual_read_buffer = nullptr;
858 }
859
861 while (ptr != nullptr) {
862 LOGD("deleting %p", ptr);
863 delete ptr;
865 }
866
867 ptr = getNextFilledBuffer();
868 while (ptr != nullptr) {
869 LOGD("deleting %p", ptr);
870 delete ptr;
871 ptr = getNextFilledBuffer();
872 }
873 }
874
876 if (actual_read_buffer != nullptr) {
879 }
880 // get next read buffer
882 }
883
885 if (available_buffers.empty()) return nullptr;
886 BaseBuffer<T> *result = nullptr;
887 available_buffers.dequeue(result);
888 return result;
889 }
890
891 virtual bool addAvailableBuffer(BaseBuffer<T> *buffer) {
892 return available_buffers.enqueue(buffer);
893 }
894
896 if (filled_buffers.empty()) return nullptr;
897 BaseBuffer<T> *result = nullptr;
898 filled_buffers.dequeue(result);
899 return result;
900 }
901
902 virtual bool addFilledBuffer(BaseBuffer<T> *buffer) {
903 return filled_buffers.enqueue(buffer);
904 }
905};
906
913template <typename T = uint8_t>
914class NBufferExt : public NBuffer<T> {
915 public:
916 NBufferExt(int size, int count) { resize(size, count); }
917
927
931 // make current read buffer available again
932 resetCurrent();
934 }
935
938 for (auto &buffer : this->filled_buffers.toVector()) {
940 if (sbuffer->id == id) {
941 return sbuffer;
942 }
943 }
944 return nullptr;
945 }
946
947 using NBuffer<T>::resize;
948
949 protected:
955 using NBuffer<T>::buffer_size;
956};
957
967template <class File, typename T>
968class NBufferFile : public BaseBuffer<T> {
969 public:
971 NBufferFile(int fileSize) { number_of_objects_per_file = fileSize; }
974
976 const char *nextFileName() {
977 next_file_name.set("buffer-");
978 char number[40];
979 snprintf(number, 40, "%d", file_count);
981 next_file_name.add(".tmp");
982 return next_file_name.c_str();
983 }
984
987 bool addFile(File &file) {
988 if (!file) return false;
989 empty_files.enqueue(file);
990 file_count++;
991 return true;
992 }
993
994 bool read(T &result) override { return readArray(&result, 1) == 1; }
995
996 int readArray(T data[], int len) override {
997 // make sure we have a read file
998 if (!read_file) {
999 if (!filled_files.dequeue(read_file)) {
1000 // no more data
1001 return 0;
1002 }
1003 read_file.seek(0);
1004 }
1005 // read the data
1006 int result = read_file.readBytes((char *)data, len * sizeof(T)) / sizeof(T);
1007
1008 // if we have consumed all content
1009 if (result < len) {
1010 read_file.seek(0);
1011 empty_files.enqueue(read_file);
1012 read_file = empty;
1013 }
1014 return result;
1015 }
1016
1017 bool peek(T &data) override {
1018 size_t pos = read_file.position();
1019 bool result = read(data);
1020 read_file.seek(pos);
1021 return result;
1022 }
1023
1024 bool write(T sample) override { return writeArray(&sample, 1) == 1; }
1025
1026 int writeArray(const T data[], int len) override {
1028 // moved to filled files
1029 if (write_file) {
1030 write_file.seek(0);
1031 filled_files.enqueue(write_file);
1032 }
1033 // get next empty file
1034 if (!empty_files.dequeue(write_file)) return false;
1035 }
1036 int result = write_file.write((uint8_t *)data, len * sizeof(T));
1037 return result / sizeof(T);
1038 }
1039
1040 int available() override {
1042 (read_file.available() / sizeof(T));
1043 }
1044
1045 // provides the number of entries that are available to write
1046 int availableForWrite() override {
1047 int open_current =
1049 return empty_files.size() * number_of_objects_per_file +
1051 }
1052
1053 size_t size() override { return number_of_objects_per_file * file_count; }
1054
1056 void end() {
1059 File file;
1060 while (empty_files.dequeue(file)) cleanupFile(file);
1061 while (filled_files.dequeue(file)) cleanupFile(file);
1062 }
1063
1065 void setFileDeleteCallback(void (*cb)(const char *filename)) {
1067 }
1068
1069 void reset() {
1070 if (read_file) {
1071 read_file.seek(0);
1072 empty_files.enqueue(read_file);
1073 read_file = empty;
1074 }
1075 if (write_file) {
1076 write_file.seek(0);
1077 empty_files.enqueue(write_file);
1078 write_file = empty;
1079 }
1080 File file;
1081 while (filled_files.dequeue(file)) {
1082 file.seek(0);
1083 empty_files.enqueue(file);
1084 }
1085 }
1087 T *address() { return nullptr; }
1088
1089 protected:
1095 int number_of_objects_per_file = 0; // number of objects per file
1096 int file_count = 0; // number of files
1100
1101 void cleanupFile(File &file) {
1102 if (!file) return;
1103 // after close the file name is gone
1104 int len = strlen(file.name());
1105 char file_name[len + 1];
1106 strncpy(file_name, file.name(), len);
1107 file.close();
1108 file_delete_callback(file_name);
1109 }
1110};
1111
1121template <typename T = uint8_t>
1123 public:
1124 BufferedArray(Stream &input, int len) {
1125 LOGI("BufferedArray(%d)", len);
1126 array.resize(len);
1127 p_stream = &input;
1128 }
1129 // access values, the offset and length are specified in samples of type <T>
1130 int16_t *getValues(size_t offset, size_t length) {
1131 LOGD("getValues(%d,%d) - max %d", offset, length, array.size());
1132 if (offset == 0) {
1133 // we restart at the beginning
1134 last_end = 0;
1135 actual_end = length;
1136 } else {
1137 // if first position is at end we do not want to read the full buffer
1138 last_end = actual_end >= 0 ? actual_end : offset;
1139 // increase actual end if bigger then old
1140 actual_end = offset + length > actual_end ? offset + length : actual_end;
1141 }
1142 int size = actual_end - last_end;
1143 if (size > 0) {
1144 LOGD("readBytes(%d,%d)", last_end, size);
1145 assert(last_end + size <= array.size());
1146 p_stream->readBytes((uint8_t *)(&array[last_end]), size * 2);
1147 }
1148 assert(offset < actual_end);
1149 return &array[offset];
1150 }
1151
1152 protected:
1153 int actual_end = -1;
1154 int last_end = 0;
1156 Stream *p_stream = nullptr;
1157};
1158
1159} // namespace audio_tools
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define LOG_METHOD
Definition AudioToolsConfig.h:74
#define assert(T)
Definition avr.h:10
Definition Arduino.h:136
virtual size_t readBytes(uint8_t *data, size_t len)
Definition Arduino.h:140
Memory allocateator which uses malloc.
Definition Allocator.h:24
Shared functionality of all buffers.
Definition Buffers.h:23
BaseBuffer(const BaseBuffer &)=default
virtual bool read(T &result)=0
reads a single value
virtual ~BaseBuffer()=default
virtual int readArray(T data[], int len)
reads multiple values
Definition Buffers.h:34
virtual void reset()=0
clears the buffer
virtual int bufferCountEmpty()
Provides the number of entries that are available to write: -1 does not apply.
Definition Buffers.h:131
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition Buffers.h:56
virtual bool resize(size_t bytes)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:122
virtual T * address()=0
returns the address of the start of the physical read buffer
virtual int writeArrayOverwrite(const T data[], int len)
Fills the buffer data and overwrites the oldest data if the buffer is full.
Definition Buffers.h:73
virtual size_t size()=0
virtual int clearArray(int len)
Removes the next len entries.
Definition Buffers.h:48
BaseBuffer & operator=(const BaseBuffer &)=default
virtual int availableForWrite()=0
provides the number of entries that are available to write
virtual int bufferCountFilled()
Provides the number of entries that are available to read: -1 does not apply.
Definition Buffers.h:128
virtual bool isFull()
checks if the buffer is full
Definition Buffers.h:85
virtual bool peek(T &result)=0
peeks the actual entry from the buffer
virtual float levelPercent()
Returns the level of the buffer in %.
Definition Buffers.h:114
void clear()
same as reset
Definition Buffers.h:96
virtual void flush()
Definition Buffers.h:100
virtual bool write(T data)=0
write add an entry to the buffer
virtual int available()=0
provides the number of entries that are available to read
bool isEmpty()
Definition Buffers.h:87
Class which is usfull ot provide incremental data access e.g. for EdgeImpulse which request data with...
Definition Buffers.h:1122
int16_t * getValues(size_t offset, size_t length)
Definition Buffers.h:1130
BufferedArray(Stream &input, int len)
Definition Buffers.h:1124
Stream * p_stream
Definition Buffers.h:1156
int last_end
Definition Buffers.h:1154
Vector< T > array
Definition Buffers.h:1155
int actual_end
Definition Buffers.h:1153
A FrameBuffer reads multiple values for array of 2 dimensional frames.
Definition Buffers.h:139
BaseBuffer< T > * p_buffer
Definition Buffers.h:172
FrameBuffer(BaseBuffer< T > &buffer)
Definition Buffers.h:141
int readFrames(T(&data)[rows][channels])
Definition Buffers.h:158
int readFrames(T data[][2], int len)
reads multiple values for array of 2 dimensional frames
Definition Buffers.h:143
A NBufferExt is a subclass of NBuffer which allows to use a direct access API to the BaseBuffer.
Definition Buffers.h:914
SingleBuffer< T > * getBuffer(int id)
Provides the buffer with the indicated id.
Definition Buffers.h:937
NBufferExt(int size, int count)
Definition Buffers.h:916
SingleBuffer< T > * readEnd()
Definition Buffers.h:930
SingleBuffer< T > * writeEnd()
Definition Buffers.h:920
A File backed buffer which uses the provided files for buffering with the indicated max size....
Definition Buffers.h:968
Str next_file_name
Definition Buffers.h:1098
const char * nextFileName()
Determines the next unique file name (after calling addFile)
Definition Buffers.h:976
size_t size() override
Definition Buffers.h:1053
void setFileDeleteCallback(void(*cb)(const char *filename))
Define the file delete operation.
Definition Buffers.h:1065
bool peek(T &data) override
peeks the actual entry from the buffer
Definition Buffers.h:1017
void(* file_delete_callback)(const char *filename)
Definition Buffers.h:1099
bool write(T sample) override
write add an entry to the buffer
Definition Buffers.h:1024
~NBufferFile()
RAII close the files.
Definition Buffers.h:973
void cleanupFile(File &file)
Definition Buffers.h:1101
bool read(T &result) override
reads a single value
Definition Buffers.h:994
int available() override
provides the number of entries that are available to read
Definition Buffers.h:1040
Queue< File > empty_files
Definition Buffers.h:1090
File read_file
Definition Buffers.h:1092
bool addFile(File &file)
Definition Buffers.h:987
File write_file
Definition Buffers.h:1093
int availableForWrite() override
provides the number of entries that are available to write
Definition Buffers.h:1046
const uint16_t max_file_name
Definition Buffers.h:1097
NBufferFile(int fileSize)
Provide the file size in objects!
Definition Buffers.h:971
int number_of_objects_per_file
Definition Buffers.h:1095
int writeArray(const T data[], int len) override
Fills the buffer data.
Definition Buffers.h:1026
void end()
clean up files
Definition Buffers.h:1056
Queue< File > filled_files
Definition Buffers.h:1091
int file_count
Definition Buffers.h:1096
File empty
Definition Buffers.h:1094
void reset()
clears the buffer
Definition Buffers.h:1069
T * address()
not supported
Definition Buffers.h:1087
int readArray(T data[], int len) override
reads multiple values
Definition Buffers.h:996
A lock free N buffer. If count=2 we create a DoubleBuffer, if count=3 a TripleBuffer etc.
Definition Buffers.h:675
unsigned long start_time
Definition Buffers.h:842
size_t size()
Provides the total capacity (=buffer size * buffer count)
Definition Buffers.h:833
QueueFromVector< BaseBuffer< T > * > available_buffers
Definition Buffers.h:840
void resetCurrent()
Definition Buffers.h:875
virtual ~NBuffer()
Definition Buffers.h:679
virtual int bufferCountEmpty()
Provides the number of entries that are available to write.
Definition Buffers.h:806
NBuffer()=default
empty constructor only allowed by subclass
virtual bool resize(size_t bytes)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:808
bool isFull()
checks if the buffer is full
Definition Buffers.h:707
bool peek(T &result) override
peeks the actual entry from the buffer
Definition Buffers.h:701
int available()
determines the available entries for the current read buffer
Definition Buffers.h:733
bool read(T &result) override
reads an entry from the buffer
Definition Buffers.h:682
bool write(T data)
write add an entry to the buffer
Definition Buffers.h:710
void freeMemory()
Definition Buffers.h:848
int availableForWrite()
determines the available entries for the write buffer
Definition Buffers.h:751
virtual bool addAvailableBuffer(BaseBuffer< T > *buffer)
Definition Buffers.h:891
NBuffer(int size, int count)
Definition Buffers.h:677
virtual bool resize(size_t size, int count)
Resize the buffers by defining a new buffer size and buffer count.
Definition Buffers.h:814
virtual int bufferCountFilled()
Provides the number of entries that are available to read.
Definition Buffers.h:803
uint16_t buffer_count
Definition Buffers.h:837
virtual bool addFilledBuffer(BaseBuffer< T > *buffer)
Definition Buffers.h:902
void reset()
resets all buffers
Definition Buffers.h:780
unsigned long sampleRate()
provides the actual sample rate
Definition Buffers.h:791
BaseBuffer< T > * actual_read_buffer
Definition Buffers.h:838
void flush()
Definition Buffers.h:772
T * address()
returns the address of the start of the phsical read buffer
Definition Buffers.h:797
BaseBuffer< T > * actual_write_buffer
Definition Buffers.h:839
QueueFromVector< BaseBuffer< T > * > filled_buffers
Definition Buffers.h:841
virtual BaseBuffer< T > * getNextAvailableBuffer()
Definition Buffers.h:884
unsigned long sample_count
Definition Buffers.h:843
int readArray(T data[], int len) override
Definition Buffers.h:690
int buffer_size
Definition Buffers.h:836
virtual BaseBuffer< T > * getNextFilledBuffer()
Definition Buffers.h:895
FIFO Queue which is based on a Vector.
Definition QueueFromVector.h:14
FIFO Queue which is based on a List.
Definition Queue.h:14
An File backed Ring Buffer that we can use to receive streaming audio. We expect an open file as para...
Definition Buffers.h:464
int readArray(T data[], int count) override
reads multiple values
Definition Buffers.h:489
size_t size() override
Provides the capacity.
Definition Buffers.h:585
int peekArray(T data[], int count)
gets multiple values w/o removing them
Definition Buffers.h:524
int file_write(const T *data, int count)
Reed the indicated number of objects.
Definition Buffers.h:641
bool peek(T &result) override
peeks the actual entry from the buffer
Definition Buffers.h:513
RingBufferFile(int size, File &file)
Definition Buffers.h:467
bool read(T &result) override
Reads a single value from the buffer.
Definition Buffers.h:486
bool write(T data) override
write add a single entry to the buffer
Definition Buffers.h:540
int available() override
provides the number of entries that are available to read
Definition Buffers.h:579
~RingBufferFile()
Definition Buffers.h:471
File * p_file
Definition Buffers.h:597
int availableForWrite() override
provides the number of entries that are available to write
Definition Buffers.h:582
int write_pos
Definition Buffers.h:598
T * address() override
returns the address of the start of the physical read buffer
Definition Buffers.h:594
bool isFull() override
checks if the buffer is full
Definition Buffers.h:566
int read_pos
Definition Buffers.h:599
bool begin(File &bufferFile)
Assigns the p_file to be used.
Definition Buffers.h:476
int max_size
Definition Buffers.h:601
bool file_seek(int pos)
Seeks to the given object position.
Definition Buffers.h:628
int writeArray(const T data[], int len) override
Fills the data from the buffer.
Definition Buffers.h:543
RingBufferFile(int size)
Definition Buffers.h:466
int file_read(T *result, int count)
Writes the indicated number of objects.
Definition Buffers.h:655
OffsetInfo getOffset(int pos, int len)
Definition Buffers.h:611
bool resize(size_t size)
Defines the capacity.
Definition Buffers.h:588
void reset() override
clears the buffer
Definition Buffers.h:571
int element_count
Definition Buffers.h:600
bool isEmpty()
Definition Buffers.h:568
Implements a typed Ringbuffer.
Definition Buffers.h:353
RingBuffer(int size, Allocator &allocator=DefaultAllocator)
Definition Buffers.h:355
bool peek(T &result) override
peeks the actual entry from the buffer
Definition Buffers.h:373
virtual int peekArray(T *data, int n)
Definition Buffers.h:382
bool read(T &result) override
reads a single value
Definition Buffers.h:360
virtual T * address() override
returns the address of the start of the physical read buffer
Definition Buffers.h:428
int nextIndex(int index)
Definition Buffers.h:450
virtual int availableForWrite() override
provides the number of entries that are available to write
Definition Buffers.h:425
virtual bool write(T data) override
write add an entry to the buffer
Definition Buffers.h:403
virtual size_t size() override
Returns the maximum capacity of the buffer.
Definition Buffers.h:440
int max_size
Definition Buffers.h:448
virtual void reset() override
clears the buffer
Definition Buffers.h:415
Allocator & _allocator
Definition Buffers.h:443
int _iHead
Definition Buffers.h:445
virtual bool isFull() override
checks if the buffer is full
Definition Buffers.h:398
int _numElems
Definition Buffers.h:447
Vector< T > _aucBuffer
Definition Buffers.h:444
virtual bool resize(size_t len)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:430
bool isEmpty()
Definition Buffers.h:400
int _iTail
Definition Buffers.h:446
virtual int available() override
provides the number of entries that are available to read
Definition Buffers.h:422
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition Buffers.h:184
bool active
Optional active/inactive status.
Definition Buffers.h:334
size_t size() override
Definition Buffers.h:315
SingleBuffer & operator=(const SingleBuffer &)=default
size_t setAvailable(size_t available_size)
Definition Buffers.h:308
void trim()
Moves the unprocessed data to the beginning of the buffer.
Definition Buffers.h:285
bool write(T sample) override
write add an entry to the buffer
Definition Buffers.h:218
Allocator _allocator
Definition Buffers.h:339
void setClearWithZero(bool flag)
Sets the buffer to 0 on clear.
Definition Buffers.h:326
bool peek(T &result) override
peeks the actual entry from the buffer
Definition Buffers.h:236
bool owns_buffer
Definition Buffers.h:342
uint64_t timestamp
Optional timestamp.
Definition Buffers.h:336
void setWritePos(int pos)
Updates the actual available data size.
Definition Buffers.h:329
bool read(T &result) override
reads a single value
Definition Buffers.h:227
int available() override
provides the number of entries that are available to read
Definition Buffers.h:245
bool is_clear_with_zero
Definition Buffers.h:343
int availableForWrite() override
provides the number of entries that are available to write
Definition Buffers.h:250
T * address() override
Provides address to beginning of the buffer.
Definition Buffers.h:293
bool isFull() override
checks if the buffer is full
Definition Buffers.h:252
int current_read_pos
Definition Buffers.h:340
void onExternalBufferRefilled(void *data, int len)
notifies that the external buffer has been refilled
Definition Buffers.h:206
int current_write_pos
Definition Buffers.h:341
int writeArray(const T data[], int len) override
Fills the buffer data.
Definition Buffers.h:213
int peekArray(uint8_t *data, int len)
Definition Buffers.h:254
Vector< T > buffer
Definition Buffers.h:344
SingleBuffer(const SingleBuffer &)=default
SingleBuffer(int size, Allocator &allocator=DefaultAllocator)
Construct a new Single Buffer object.
Definition Buffers.h:191
SingleBuffer()
Construct a new Single Buffer w/o allocating any memory.
Definition Buffers.h:203
T * data()
Provides address of actual data.
Definition Buffers.h:296
bool resize(size_t size)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:317
void reset() override
clears the buffer
Definition Buffers.h:298
int clearArray(int len) override
consumes len bytes and moves current data to the beginning
Definition Buffers.h:264
Str which keeps the data on the heap. We grow the allocated memory only if the copy source is not fit...
Definition Str.h:24
virtual void set(const char *alt)
assigs a value
Definition StrView.h:47
virtual const char * c_str()
provides the string value as const char*
Definition StrView.h:380
virtual void add(int value)
adds a int value
Definition StrView.h:126
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
Arduino File API for Zephyr.
Definition ZephyrFile.h:23
void flush() override
Definition ZephyrFile.h:152
size_t size() const
Definition ZephyrFile.h:198
size_t write(uint8_t value) override
Definition ZephyrFile.h:129
void close()
Definition ZephyrFile.h:67
int available() override
Definition ZephyrFile.h:89
size_t position() const
Definition ZephyrFile.h:188
size_t readBytes(char *buffer, size_t len)
Definition ZephyrFile.h:119
const char * name() const
Definition ZephyrFile.h:200
bool seek(size_t pos)
Definition ZephyrFile.h:180
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
static TAllocatorExt DefaultAllocator
Definition Allocator.h:207
uint32_t millis()
Returns the milliseconds since the start.
Definition Arduino.h:256
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
int pos
Definition Buffers.h:604
int len1
Definition Buffers.h:606
int len
Definition Buffers.h:605