arduino-audio-tools
BufferRTOS.h
1 #pragma once
2 #include "AudioConfig.h"
3 #include "AudioTools/Buffers.h"
4 #include "AudioTools/AudioLogger.h"
5 #include "AudioBasic/Collections/Allocator.h"
6 
7 #if defined(USE_CONCURRENCY)
8 #ifdef ESP32
9 # include <freertos/stream_buffer.h>
10 # include "freertos/FreeRTOS.h"
11 #else
12 # include "FreeRTOS.h"
13 # include "stream_buffer.h"
14 #endif
15 
16 namespace audio_tools {
17 
18 // #if ESP_IDF_VERSION_MAJOR >= 4
19 
29 template <typename T>
30 class BufferRTOS : public BaseBuffer<T> {
31  public:
32  BufferRTOS(size_t xStreamBufferSizeBytes, size_t xTriggerLevel = 1,
33  TickType_t writeMaxWait = portMAX_DELAY,
34  TickType_t readMaxWait = portMAX_DELAY,
35  Allocator &allocator = DefaultAllocator)
36  : BaseBuffer<T>() {
37  readWait = readMaxWait;
38  writeWait = writeMaxWait;
39  current_size = xStreamBufferSizeBytes;
40  trigger_level = xTriggerLevel;
41  p_allocator = &allocator;
42 
43  if (current_size > 0) {
44  setup();
45  }
46  }
47 
48  ~BufferRTOS() { end(); }
49 
51  void resize(size_t size) {
52  if (current_size != size) {
53  end();
54  current_size = size;
55  setup();
56  }
57  }
58 
59  void setReadMaxWait(TickType_t ticks) { readWait = ticks; }
60 
61  void setWriteMaxWait(TickType_t ticks) { writeWait = ticks; }
62 
63  void setWriteFromISR(bool active) { write_from_isr = active; }
64 
65  void setReadFromISR(bool active) { read_from_isr = active; }
66 
67  // reads a single value
68  T read() override {
69  T data = 0;
70  readArray(&data, sizeof(T));
71  return data;
72  }
73 
74  // reads multiple values
75  int readArray(T data[], int len) {
76  if (read_from_isr) {
77  xHigherPriorityTaskWoken = pdFALSE;
78  int result = xStreamBufferReceiveFromISR(xStreamBuffer, (void *)data,
79  sizeof(T) * len,
80  &xHigherPriorityTaskWoken);
81 #ifdef ESP32X
82  portYIELD_FROM_ISR();
83 #else
84  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
85 #endif
86  return result;
87  } else {
88  return xStreamBufferReceive(xStreamBuffer, (void *)data, sizeof(T) * len,
89  readWait);
90  }
91  }
92 
93  int writeArray(const T data[], int len) {
94  LOGD("%s: %d", LOG_METHOD, len);
95  if (write_from_isr) {
96  xHigherPriorityTaskWoken = pdFALSE;
97  int result =
98  xStreamBufferSendFromISR(xStreamBuffer, (void *)data, sizeof(T) * len,
99  &xHigherPriorityTaskWoken);
100 #ifdef ESP32X
101  portYIELD_FROM_ISR();
102 #else
103  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
104 #endif
105  return result;
106  } else {
107  return xStreamBufferSend(xStreamBuffer, (void *)data, sizeof(T) * len,
108  writeWait);
109  }
110  }
111 
112  // peeks the actual entry from the buffer
113  T peek() override {
114  LOGE("peek not implmented");
115  return 0;
116  }
117 
118  // checks if the buffer is full
119  bool isFull() override {
120  return xStreamBufferIsFull(xStreamBuffer) == pdTRUE;
121  }
122 
123  bool isEmpty() { return xStreamBufferIsEmpty(xStreamBuffer) == pdTRUE; }
124 
125  // write add an entry to the buffer
126  bool write(T data) override {
127  int len = sizeof(T);
128  return writeArray(&data, len) == len;
129  }
130 
131  // clears the buffer
132  void reset() override { xStreamBufferReset(xStreamBuffer); }
133 
134  // provides the number of entries that are available to read
135  int available() override {
136  return xStreamBufferBytesAvailable(xStreamBuffer);
137  }
138 
139  // provides the number of entries that are available to write
140  int availableForWrite() override {
141  return xStreamBufferSpacesAvailable(xStreamBuffer);
142  }
143 
144  // returns the address of the start of the physical read buffer
145  T *address() override {
146  LOGE("address() not implemented");
147  return nullptr;
148  }
149 
150  size_t size() { return current_size; }
151 
152  protected:
153  StreamBufferHandle_t xStreamBuffer = nullptr;
154  StaticStreamBuffer_t static_stream_buffer;
155  uint8_t *p_data = nullptr;
156  Allocator *p_allocator = nullptr;
157  BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
158  int readWait = portMAX_DELAY;
159  int writeWait = portMAX_DELAY;
160  bool read_from_isr = false;
161  bool write_from_isr = false;
162  size_t current_size = 0;
163  size_t trigger_level = 0;
164 
167  bool setup() {
168  if (current_size == 0) return true;
169 
170  // allocate data if necessary
171  if (p_data == nullptr) {
172  p_data = (uint8_t *)p_allocator->allocate((current_size + 1) * sizeof(T));
173  }
174  if (p_data == nullptr) return false;
175 
176  // create stream buffer if necessary
177  if (xStreamBuffer == nullptr) {
178  xStreamBuffer = xStreamBufferCreateStatic(current_size, trigger_level,
179  p_data, &static_stream_buffer);
180  }
181  if (xStreamBuffer == nullptr) return false;
182  // make sure that the data is empty
183  reset();
184  return true;
185  }
186 
188  void end() {
189  if (xStreamBuffer != nullptr) vStreamBufferDelete(xStreamBuffer);
190  p_allocator->free(p_data);
191  current_size = 0;
192  p_data = nullptr;
193  xStreamBuffer = nullptr;
194  }
195 };
196 // #endif // ESP_IDF_VERSION_MAJOR >= 4
197 
198 template <class T>
199 using SynchronizedBufferRTOS = BufferRTOS<T>;
200 
201 } // namespace audio_tools
202 
203 #endif
Memory allocateator which uses malloc.
Definition: Allocator.h:22
Shared functionality of all buffers.
Definition: Buffers.h:30
Buffer implementation which is using a FreeRTOS StreamBuffer. The default allocator uses psram is ava...
Definition: BufferRTOS.h:30
T * address() override
returns the address of the start of the physical read buffer
Definition: BufferRTOS.h:145
T peek() override
peeks the actual entry from the buffer
Definition: BufferRTOS.h:113
void resize(size_t size)
Re-Allocats the memory and the queue.
Definition: BufferRTOS.h:51
bool write(T data) override
write add an entry to the buffer
Definition: BufferRTOS.h:126
int available() override
provides the number of entries that are available to read
Definition: BufferRTOS.h:135
int availableForWrite() override
provides the number of entries that are available to write
Definition: BufferRTOS.h:140
bool isFull() override
checks if the buffer is full
Definition: BufferRTOS.h:119
void end()
Release resurces: call resize to restart again.
Definition: BufferRTOS.h:188
int writeArray(const T data[], int len)
Fills the buffer data.
Definition: BufferRTOS.h:93
void reset() override
clears the buffer
Definition: BufferRTOS.h:132
T read() override
reads a single value
Definition: BufferRTOS.h:68
bool setup()
Definition: BufferRTOS.h:167
int readArray(T data[], int len)
reads multiple values
Definition: BufferRTOS.h:75
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AnalogAudio.h:10