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