arduino-audio-tools
Buffers.h
1 
2 #pragma once
3 
4 #include "AudioBasic/Collections.h"
5 #include "AudioTools/AudioLogger.h"
6 
7 #ifndef INT_MAX
8 # define INT_MAX 2147483647
9 #endif
10 
17 namespace audio_tools {
18 
19 // forward declaration
20 template <typename T>
21 class NBuffer;
22 
29 template <typename T>
30 class BaseBuffer {
31  public:
32  BaseBuffer() = default;
33  virtual ~BaseBuffer() = default;
34  BaseBuffer(BaseBuffer const &) = delete;
35  BaseBuffer &operator=(BaseBuffer const &) = delete;
36 
38  virtual T read() = 0;
39 
41  virtual int readArray(T data[], int len) {
42  if (data==nullptr){
43  LOGE("NPE");
44  return 0;
45  }
46  int lenResult = min(len, available());
47  for (int j = 0; j < lenResult; j++) {
48  data[j] = read();
49  }
50  LOGD("readArray %d -> %d", len, lenResult);
51  return lenResult;
52  }
53 
55  virtual int clearArray(int len) {
56  int lenResult = min(len, available());
57  for (int j = 0; j < lenResult; j++) {
58  read();
59  }
60  return lenResult;
61  }
62 
63 
65  virtual int writeArray(const T data[], int len) {
66  // LOGD("%s: %d", LOG_METHOD, len);
67  // CHECK_MEMORY();
68 
69  int result = 0;
70  for (int j = 0; j < len; j++) {
71  if (!write(data[j])) {
72  break;
73  }
74  result = j + 1;
75  }
76  // CHECK_MEMORY();
77  LOGD("writeArray %d -> %d", len, result);
78  return result;
79  }
80 
81 
83  virtual int writeArrayOverwrite(const T data[], int len) {
84  int to_delete = len - availableForWrite();
85  if (to_delete>0){
86  clearArray(to_delete);
87  }
88  return writeArray(data, len);
89  }
90 
91 
93  int readFrames(T data[][2], int len) {
94  LOGD("%s: %d", LOG_METHOD, len);
95  // CHECK_MEMORY();
96  int result = min(len, available());
97  for (int j = 0; j < result; j++) {
98  T sample = read();
99  data[j][0] = sample;
100  data[j][1] = sample;
101  }
102  // CHECK_MEMORY();
103  return result;
104  }
105 
106  template <int rows, int channels>
107  int readFrames(T (&data)[rows][channels]) {
108  int lenResult = min(rows, available());
109  for (int j = 0; j < lenResult; j++) {
110  T sample = read();
111  for (int i = 0; i < channels; i++) {
112  // data[j][i] = htons(sample);
113  data[j][i] = sample;
114  }
115  }
116  return lenResult;
117  }
118 
120  virtual T peek() = 0;
121 
123  virtual bool isFull() = 0;
124 
125  bool isEmpty() { return available() == 0; }
126 
128  virtual bool write(T data) = 0;
129 
131  virtual void reset() = 0;
132 
134  void clear() { reset(); }
135 
137  virtual int available() = 0;
138 
140  virtual int availableForWrite() = 0;
141 
143  virtual T *address() = 0;
144 
145  virtual size_t size() = 0;
146 
147  protected:
148  void setWritePos(int pos){};
149 
150  friend NBuffer<T>;
151 };
152 
161 template <typename T>
162 class SingleBuffer : public BaseBuffer<T> {
163  public:
169  SingleBuffer(int size) {
170  this->max_size = size;
171  buffer.resize(max_size);
172  reset();
173  }
174 
179 
181  void onExternalBufferRefilled(void *data, int len) {
182  this->owns_buffer = false;
183  this->buffer = (uint8_t *)data;
184  this->current_read_pos = 0;
185  this->current_write_pos = len;
186  }
187 
188  bool write(T sample) override {
189  bool result = false;
190  if (current_write_pos < max_size) {
191  buffer[current_write_pos++] = sample;
192  result = true;
193  }
194  return result;
195  }
196 
197  T read() override {
198  T result = 0;
199  if (current_read_pos < current_write_pos) {
200  result = buffer[current_read_pos++];
201  }
202  return result;
203  }
204 
205  T peek() override {
206  T result = 0;
207  if (current_read_pos < current_write_pos) {
208  result = buffer[current_read_pos];
209  }
210  return result;
211  }
212 
213  int available() override {
214  int result = current_write_pos - current_read_pos;
215  return max(result, 0);
216  }
217 
218  int availableForWrite() override { return max_size - current_write_pos; }
219 
220  bool isFull() override { return availableForWrite() <= 0; }
221 
223  int clearArray(int len) override{
224  int len_available = available();
225  if (len>available()) {
226  reset();
227  return len_available;
228  }
229  current_read_pos += len;
230  len_available -= len;
231  memmove(buffer.data(), buffer.data()+current_read_pos, len_available);
232  current_read_pos = 0;
233  current_write_pos = len_available;
234 
235  if (is_clear_with_zero){
236  memset(buffer.data()+current_write_pos,0,buffer.size()-current_write_pos);
237  }
238 
239  return len;
240  }
241 
243  T *address() override { return buffer.data(); }
244 
246  T *data() { return buffer.data()+current_read_pos; }
247 
248  void reset() override {
249  current_read_pos = 0;
250  current_write_pos = 0;
251  if (is_clear_with_zero){
252  memset(buffer.data(),0,buffer.size());
253  }
254  }
255 
258  size_t setAvailable(size_t available_size) {
259  size_t result = min(available_size, (size_t) max_size);
260  current_read_pos = 0;
261  current_write_pos = result;
262  return result;
263  }
264 
265 
266  size_t size() { return max_size; }
267 
268  void resize(int size) {
269  if (buffer.size() != size) {
270  TRACED();
271  buffer.resize(size);
272  max_size = size;
273  }
274  }
275 
277  void setClearWithZero(bool flag){
278  is_clear_with_zero = flag;
279  }
280 
281  protected:
282  int max_size = 0;
283  int current_read_pos = 0;
284  int current_write_pos = 0;
285  bool owns_buffer = true;
286  bool is_clear_with_zero = false;
287  Vector<T> buffer{0};
288 
289  void setWritePos(int pos) { current_write_pos = pos; }
290 };
291 
297 template <typename T>
298 class RingBuffer : public BaseBuffer<T> {
299  public:
300  RingBuffer(int size) {
301  resize(size);
302  reset();
303  }
304 
305  virtual T read() {
306  if (isEmpty()) return -1;
307 
308  T value = _aucBuffer[_iTail];
309  _iTail = nextIndex(_iTail);
310  _numElems--;
311 
312  return value;
313  }
314 
315  // peeks the actual entry from the buffer
316  virtual T peek() {
317  if (isEmpty()) return -1;
318 
319  return _aucBuffer[_iTail];
320  }
321 
322  virtual int peekArray(T*data, int n){
323  if (isEmpty()) return -1;
324  int result = 0;
325  int count = _numElems;
326  int tail = _iTail;
327  for (int j=0;j<n;j++){
328  data[j] = _aucBuffer[tail];
329  tail = nextIndex(tail);
330  count--;
331  result++;
332  if (count==0)break;
333  }
334  return result;
335  }
336 
337  // checks if the buffer is full
338  virtual bool isFull() { return available() == max_size; }
339 
340  bool isEmpty() { return available() == 0; }
341 
342  // write add an entry to the buffer
343  virtual bool write(T data) {
344  bool result = false;
345  if (!isFull()) {
346  _aucBuffer[_iHead] = data;
347  _iHead = nextIndex(_iHead);
348  _numElems++;
349  result = true;
350  }
351  return result;
352  }
353 
354  // clears the buffer
355  virtual void reset() {
356  _iHead = 0;
357  _iTail = 0;
358  _numElems = 0;
359  }
360 
361  // provides the number of entries that are available to read
362  virtual int available() { return _numElems; }
363 
364  // provides the number of entries that are available to write
365  virtual int availableForWrite() { return (max_size - _numElems); }
366 
367  // returns the address of the start of the physical read buffer
368  virtual T *address() { return _aucBuffer.data(); }
369 
370  virtual void resize(int len) {
371  if (max_size != len) {
372  LOGI("resize: %d", len);
373  _aucBuffer.resize(len);
374  max_size = len;
375  }
376  }
377 
379  virtual size_t size() { return max_size; }
380 
381  protected:
382  Vector<T> _aucBuffer;
383  int _iHead;
384  int _iTail;
385  int _numElems;
386  int max_size = 0;
387 
388  int nextIndex(int index) { return (uint32_t)(index + 1) % max_size; }
389 };
390 
401 template <class File, typename T>
402 class RingBufferFile : public BaseBuffer<T> {
403  public:
404  RingBufferFile(bool autoRewind = true) { setAutoRewind(autoRewind); }
405  RingBufferFile(File &file, bool autoRewind = true) {
406  setFile(file);
407  setAutoRewind(autoRewind);
408  }
409 
413  void setAutoRewind(bool flag) { auto_rewind = true; }
414 
416  void setFile(File &bufferFile, bool clear = false) {
417  p_file = &bufferFile;
418  if (!*p_file) {
419  LOGE("file is not valid");
420  }
421  // if no clear has been requested we can access the existing data in the
422  // p_file
423  if (!clear) {
424  element_count = p_file->size() / sizeof(T);
425  LOGI("existing elements: %s", element_count);
426  read_pos = element_count;
427  }
428  }
429 
430  T read() override {
431  if (isEmpty()) return -1;
432 
433  T result = peek();
434  read_pos++;
435  element_count--;
436  // the buffer is empty
437  if (auto_rewind && isEmpty()) {
438  LOGI("pos 0");
439  write_pos = 0;
440  read_pos = 0;
441  }
442 
443  return result;
444  }
445 
447  int readArray(T data[], int count) override {
448  if (p_file == nullptr) return 0;
449  int read_count = min(count, element_count);
450  file_seek(read_pos);
451  int elements_processed = file_read(data, read_count);
452  read_pos += elements_processed;
453  element_count -= elements_processed;
454  return elements_processed;
455  }
456 
457  // peeks the actual entry from the buffer
458  T peek() override {
459  if (p_file == nullptr) return 0;
460  if (isEmpty()) return -1;
461 
462  file_seek(read_pos);
463  T result;
464  size_t count = file_read(&result, 1);
465  return result;
466  }
467 
468  // checks if the buffer is full
469  bool isFull() override { return available() == max_size; }
470 
471  bool isEmpty() { return available() == 0; }
472 
473  // write add an entry to the buffer
474  virtual bool write(T data) override { return writeArray(&data, 1); }
475 
477  int writeArray(const T data[], int len) override {
478  if (p_file == nullptr) return 0;
479  file_seek(write_pos);
480  int elements_written = file_write(data, len);
481  write_pos += elements_written;
482  element_count += elements_written;
483  return elements_written;
484  }
485 
486  // clears the buffer
487  void reset() override {
488  write_pos = 0;
489  read_pos = 0;
490  element_count = 0;
491  if (p_file != nullptr) file_seek(0);
492  }
493 
494  // provides the number of entries that are available to read
495  int available() override { return element_count; }
496 
497  // provides the number of entries that are available to write
498  int availableForWrite() override { return (max_size - element_count); }
499 
500  // /// Returns the maximum capacity of the buffer
501  // int size() override { return max_size; }
502 
503  // not supported
504  T *address() override { return nullptr; }
505 
506  size_t size() override {
507  return write_pos - read_pos;
508  }
509 
510  protected:
511  File *p_file = nullptr;
512  int write_pos;
513  int read_pos;
514  int element_count;
515  int max_size = INT_MAX;
516  bool auto_rewind = true;
517 
518  void file_seek(int pos) {
519  if (p_file->position() != pos * sizeof(T)) {
520  LOGD("file_seek: %d", pos);
521  if (!p_file->seek(pos * sizeof(T))) {
522  LOGE("seek %d", pos * sizeof(T))
523  }
524  }
525  }
526 
527  int file_write(const T *data, int count) {
528  LOGD("file_write: %d", count);
529  if (p_file == nullptr) return 0;
530  int to_write = sizeof(T) * count;
531  int bytes_written = p_file->write((const uint8_t *)data, to_write);
532  // p_file->flush();
533  int elements_written = bytes_written / sizeof(T);
534  if (bytes_written != to_write) {
535  LOGE("write: %d -> %d", to_write, bytes_written);
536  }
537  return elements_written;
538  }
539 
540  int file_read(T *result, int count) {
541  LOGD("file_read: %d", count);
542  size_t result_bytes = p_file->read((uint8_t *)result, sizeof(T) * count);
543  if (result_bytes != count * sizeof(T)) {
544  LOGE("readBytes: %d -> %d", (int)sizeof(T) * count, (int)result_bytes);
545  result = 0;
546  }
547  return count;
548  }
549 };
550 
558 template <typename T>
559 class NBuffer : public BaseBuffer<T> {
560  public:
561  NBuffer(int size, int count) {
562  resize(size, count);
563  }
564 
565  virtual ~NBuffer() {
566  freeMemory();
567  }
568 
569  // reads an entry from the buffer
570  T read() {
571  T result = 0;
572  if (available() > 0) {
573  result = actual_read_buffer->read();
574  }
575  return result;
576  }
577 
578  // peeks the actual entry from the buffer
579  T peek() {
580  T result = 0;
581  if (available() > 0) {
582  result = actual_read_buffer->peek();
583  }
584  return result;
585  }
586 
587  // checks if the buffer is full
588  bool isFull() { return availableForWrite() == 0; }
589 
590  // write add an entry to the buffer
591  bool write(T data) {
592  bool result = false;
593  if (actual_write_buffer == nullptr) {
594  actual_write_buffer = getNextAvailableBuffer();
595  }
596  if (actual_write_buffer != nullptr) {
597  result = actual_write_buffer->write(data);
598  // if buffer is full move to next available
599  if (actual_write_buffer->isFull()) {
600  addFilledBuffer(actual_write_buffer);
601  actual_write_buffer = getNextAvailableBuffer();
602  }
603  } else {
604  // Logger.debug("actual_write_buffer is full");
605  }
606 
607  if (start_time == 0l) {
608  start_time = millis();
609  }
610  sample_count++;
611 
612  return result;
613  }
614 
615  // determines the available entries for the current read buffer
616  int available() {
617  if (actual_read_buffer == nullptr) {
618  actual_read_buffer = getNextFilledBuffer();
619  }
620  if (actual_read_buffer == nullptr) {
621  return 0;
622  }
623  int result = actual_read_buffer->available();
624  if (result == 0) {
625  // make current read buffer available again
626  resetCurrent();
627  result =
628  actual_read_buffer == nullptr ? 0 : actual_read_buffer->available();
629  }
630  return result;
631  }
632 
633  // deterMINes the available entries for the write buffer
635  if (actual_write_buffer == nullptr) {
636  actual_write_buffer = getNextAvailableBuffer();
637  }
638  // if we used up all buffers - there is nothing available any more
639  if (actual_write_buffer == nullptr) {
640  return 0;
641  }
642  // check on actual buffer
643  if (actual_write_buffer->isFull()) {
644  // if buffer is full we move it to filled buffers ang get the next
645  // available
646  addFilledBuffer(actual_write_buffer);
647  actual_write_buffer = getNextAvailableBuffer();
648  }
649  return actual_write_buffer->availableForWrite();
650  }
651 
652  // resets all buffers
653  void reset() {
654  TRACED();
655  while (actual_read_buffer != nullptr) {
656  actual_read_buffer->reset();
657  addAvailableBuffer(actual_read_buffer);
658  // get next read buffer
659  actual_read_buffer = getNextFilledBuffer();
660  }
661  }
662 
663  // provides the actual sample rate
664  unsigned long sampleRate() {
665  unsigned long run_time = (millis() - start_time);
666  return run_time == 0 ? 0 : sample_count * 1000 / run_time;
667  }
668 
669  // returns the address of the start of the phsical read buffer
670  T *address() {
671  return actual_read_buffer == nullptr ? nullptr
672  : actual_read_buffer->address();
673  }
674 
675  // Alternative interface using address: the current buffer has been filled
676  BaseBuffer<T> &writeEnd() {
677  if (actual_write_buffer != nullptr) {
678  actual_write_buffer->setWritePos(buffer_size);
679  addFilledBuffer(actual_write_buffer);
680  }
681  actual_write_buffer = getNextAvailableBuffer();
682  return *actual_write_buffer;
683  }
684 
685  // Alternative interface using address: marks actual buffer as processed and
686  // provides access to next read buffer
687  BaseBuffer<T> &readEnd() {
688  // make current read buffer available again
689  resetCurrent();
690  return *actual_read_buffer;
691  }
692 
693  int bufferCountFilled() {
694  int result = 0;
695  for (int j = 0; j < buffer_count; j++) {
696  if (filled_buffers[j] != nullptr) {
697  result++;
698  }
699  }
700  return result;
701  }
702 
703  int bufferCountEmpty() {
704  int result = 0;
705  for (int j = 0; j < buffer_count; j++) {
706  if (avaliable_buffers[j] != nullptr) {
707  result++;
708  }
709  }
710  return result;
711  }
712 
713  void resize(int size, int count) {
714  if (buffer_size==size && buffer_count == count)
715  return;
716  freeMemory();
717  filled_buffers.resize(count);
718  avaliable_buffers.resize(count);
719 
720  write_buffer_count = 0;
721  buffer_count = count;
722  buffer_size = size;
723  for (int j = 0; j < count; j++) {
724  avaliable_buffers[j] = new SingleBuffer<T>(size);
725  if (avaliable_buffers[j] == nullptr) {
726  LOGE("Not Enough Memory for buffer %d", j);
727  }
728  }
729  }
730 
731  size_t size() { return buffer_size * buffer_count;}
732 
733  protected:
734  int buffer_size = 0;
735  uint16_t buffer_count = 0;
736  uint16_t write_buffer_count = 0;
737  BaseBuffer<T> *actual_read_buffer = nullptr;
738  BaseBuffer<T> *actual_write_buffer = nullptr;
739  Vector<BaseBuffer<T> *> avaliable_buffers;
740  Vector<BaseBuffer<T> *> filled_buffers;
741  unsigned long start_time = 0;
742  unsigned long sample_count = 0;
743 
744  // empty constructor only allowed by subclass
745  NBuffer() = default;
746 
747  void freeMemory() {
748  delete actual_write_buffer;
749  actual_write_buffer = nullptr;
750  delete actual_read_buffer;
751  actual_read_buffer = nullptr;
752 
753  BaseBuffer<T> *ptr = getNextAvailableBuffer();
754  while (ptr != nullptr) {
755  delete ptr;
756  ptr = getNextAvailableBuffer();
757  }
758 
759  ptr = getNextFilledBuffer();
760  while (ptr != nullptr) {
761  delete ptr;
762  ptr = getNextFilledBuffer();
763  }
764  }
765 
766  void resetCurrent() {
767  if (actual_read_buffer != nullptr) {
768  actual_read_buffer->reset();
769  addAvailableBuffer(actual_read_buffer);
770  }
771  // get next read buffer
772  actual_read_buffer = getNextFilledBuffer();
773  }
774 
775  virtual BaseBuffer<T> *getNextAvailableBuffer() {
776  BaseBuffer<T> *result = nullptr;
777  for (int j = 0; j < buffer_count; j++) {
778  result = avaliable_buffers[j];
779  if (result != nullptr) {
780  avaliable_buffers[j] = nullptr;
781  break;
782  }
783  }
784  return result;
785  }
786 
787  virtual bool addAvailableBuffer(BaseBuffer<T> *buffer) {
788  bool result = false;
789  for (int j = 0; j < buffer_count; j++) {
790  if (avaliable_buffers[j] == nullptr) {
791  avaliable_buffers[j] = buffer;
792  result = true;
793  break;
794  }
795  }
796  return result;
797  }
798 
799  virtual BaseBuffer<T> *getNextFilledBuffer() {
800  BaseBuffer<T> *result = nullptr;
801  if (write_buffer_count > 0) {
802  // get oldest entry
803  result = filled_buffers[0];
804  // move data by 1 entry to the left
805  for (int j = 0; j < write_buffer_count - 1; j++)
806  filled_buffers[j] = filled_buffers[j + 1];
807  // clear last enty
808  filled_buffers[write_buffer_count - 1] = nullptr;
809  write_buffer_count--;
810  }
811  return result;
812  }
813 
814  virtual bool addFilledBuffer(BaseBuffer<T> *buffer) {
815  bool result = false;
816  if (write_buffer_count < buffer_count) {
817  filled_buffers[write_buffer_count++] = buffer;
818  result = true;
819  }
820  return result;
821  }
822 };
823 
833 template <typename T>
835  public:
836  BufferedArray(Stream &input, int len) {
837  LOGI("BufferedArray(%d)", len);
838  array.resize(len);
839  p_stream = &input;
840  }
841  // access values, the offset and length are specified in samples of type <T>
842  int16_t *getValues(size_t offset, size_t length) {
843  LOGD("getValues(%d,%d) - max %d", offset, length, array.size());
844  if (offset == 0) {
845  // we restart at the beginning
846  last_end = 0;
847  actual_end = length;
848  } else {
849  // if first position is at end we do not want to read the full buffer
850  last_end = actual_end >= 0 ? actual_end : offset;
851  // increase actual end if bigger then old
852  actual_end = offset + length > actual_end ? offset + length : actual_end;
853  }
854  int size = actual_end - last_end;
855  if (size > 0) {
856  LOGD("readBytes(%d,%d)", last_end, size);
857  assert(last_end + size <= array.size());
858  p_stream->readBytes((uint8_t *)(&array[last_end]), size * 2);
859  }
860  assert(offset < actual_end);
861  return &array[offset];
862  }
863 
864  protected:
865  int actual_end = -1;
866  int last_end = 0;
867  Vector<T> array;
868  Stream *p_stream = nullptr;
869 };
870 
871 } // namespace audio_tools
Shared functionality of all buffers.
Definition: Buffers.h:30
virtual T * address()=0
returns the address of the start of the physical read buffer
virtual int readArray(T data[], int len)
reads multiple values
Definition: Buffers.h:41
virtual void reset()=0
clears the buffer
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition: Buffers.h:65
virtual bool isFull()=0
checks if the buffer is full
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:83
virtual int clearArray(int len)
Removes the next len entries.
Definition: Buffers.h:55
virtual T read()=0
reads a single value
virtual int availableForWrite()=0
provides the number of entries that are available to write
int readFrames(T data[][2], int len)
reads multiple values for array of 2 dimensional frames
Definition: Buffers.h:93
virtual T peek()=0
peeks the actual entry from the buffer
void clear()
same as reset
Definition: Buffers.h:134
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
Class which is usfull ot provide incremental data access e.g. for EdgeImpulse which request data with...
Definition: Buffers.h:834
Arduino File support using std::fstream.
Definition: File.h:25
A lock free N buffer. If count=2 we create a DoubleBuffer, if count=3 a TripleBuffer etc.
Definition: Buffers.h:559
T * address()
returns the address of the start of the physical read buffer
Definition: Buffers.h:670
bool isFull()
checks if the buffer is full
Definition: Buffers.h:588
int available()
provides the number of entries that are available to read
Definition: Buffers.h:616
bool write(T data)
write add an entry to the buffer
Definition: Buffers.h:591
T peek()
peeks the actual entry from the buffer
Definition: Buffers.h:579
int availableForWrite()
provides the number of entries that are available to write
Definition: Buffers.h:634
T read()
reads a single value
Definition: Buffers.h:570
void reset()
clears the buffer
Definition: Buffers.h:653
An File backed Ring Buffer that we can use to receive streaming audio. We expect an open p_file as pa...
Definition: Buffers.h:402
T * address() override
returns the address of the start of the physical read buffer
Definition: Buffers.h:504
int readArray(T data[], int count) override
reads multiple values
Definition: Buffers.h:447
void setFile(File &bufferFile, bool clear=false)
Assigns the p_file to be used.
Definition: Buffers.h:416
T peek() override
peeks the actual entry from the buffer
Definition: Buffers.h:458
void setAutoRewind(bool flag)
Definition: Buffers.h:413
int available() override
provides the number of entries that are available to read
Definition: Buffers.h:495
virtual bool write(T data) override
write add an entry to the buffer
Definition: Buffers.h:474
int availableForWrite() override
provides the number of entries that are available to write
Definition: Buffers.h:498
bool isFull() override
checks if the buffer is full
Definition: Buffers.h:469
int writeArray(const T data[], int len) override
Fills the data from the buffer.
Definition: Buffers.h:477
void reset() override
clears the buffer
Definition: Buffers.h:487
T read() override
reads a single value
Definition: Buffers.h:430
Implements a typed Ringbuffer.
Definition: Buffers.h:298
virtual T read()
reads a single value
Definition: Buffers.h:305
virtual int availableForWrite()
provides the number of entries that are available to write
Definition: Buffers.h:365
virtual int available()
provides the number of entries that are available to read
Definition: Buffers.h:362
virtual bool write(T data)
write add an entry to the buffer
Definition: Buffers.h:343
virtual void reset()
clears the buffer
Definition: Buffers.h:355
virtual T * address()
returns the address of the start of the physical read buffer
Definition: Buffers.h:368
virtual size_t size()
Returns the maximum capacity of the buffer.
Definition: Buffers.h:379
virtual bool isFull()
checks if the buffer is full
Definition: Buffers.h:338
virtual T peek()
peeks the actual entry from the buffer
Definition: Buffers.h:316
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition: Buffers.h:162
T * address() override
Provides address to beginning of the buffer.
Definition: Buffers.h:243
T * data()
Provides address of actual data.
Definition: Buffers.h:246
T peek() override
peeks the actual entry from the buffer
Definition: Buffers.h:205
size_t setAvailable(size_t available_size)
Definition: Buffers.h:258
bool write(T sample) override
write add an entry to the buffer
Definition: Buffers.h:188
SingleBuffer(int size)
Construct a new Single Buffer object.
Definition: Buffers.h:169
void setClearWithZero(bool flag)
Sets the buffer to 0 on clear.
Definition: Buffers.h:277
int available() override
provides the number of entries that are available to read
Definition: Buffers.h:213
int availableForWrite() override
provides the number of entries that are available to write
Definition: Buffers.h:218
bool isFull() override
checks if the buffer is full
Definition: Buffers.h:220
void onExternalBufferRefilled(void *data, int len)
notifies that the external buffer has been refilled
Definition: Buffers.h:181
SingleBuffer()
Construct a new Single Buffer w/o allocating any memory.
Definition: Buffers.h:178
void reset() override
clears the buffer
Definition: Buffers.h:248
T read() override
reads a single value
Definition: Buffers.h:197
int clearArray(int len) override
consumes len bytes and moves current data to the beginning
Definition: Buffers.h:223
Definition: NoArduino.h:125
Vector implementation which provides the most important methods as defined by std::vector....
Definition: Vector.h:21
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AnalogAudio.h:10
uint32_t millis()
Returns the milliseconds since the start.
Definition: Millis.h:18