4 #include "AudioBasic/Collections.h"
5 #include "AudioTools/AudioLogger.h"
8 # define INT_MAX 2147483647
47 for (
int j = 0; j < lenResult; j++) {
50 LOGD(
"readArray %d -> %d", len, lenResult);
57 for (
int j = 0; j < lenResult; j++) {
70 for (
int j = 0; j < len; j++) {
71 if (!
write(data[j])) {
77 LOGD(
"writeArray %d -> %d", len, result);
94 LOGD(
"%s: %d", LOG_METHOD, len);
97 for (
int j = 0; j < result; j++) {
106 template <
int rows,
int channels>
109 for (
int j = 0; j < lenResult; j++) {
111 for (
int i = 0; i < channels; i++) {
125 bool isEmpty() {
return available() == 0; }
145 virtual size_t size() = 0;
148 void setWritePos(
int pos){};
161 template <
typename T>
170 this->max_size = size;
171 buffer.resize(max_size);
182 this->owns_buffer =
false;
183 this->buffer = (uint8_t *)
data;
184 this->current_read_pos = 0;
185 this->current_write_pos = len;
190 if (current_write_pos < max_size) {
191 buffer[current_write_pos++] = sample;
199 if (current_read_pos < current_write_pos) {
200 result = buffer[current_read_pos++];
207 if (current_read_pos < current_write_pos) {
208 result = buffer[current_read_pos];
214 int result = current_write_pos - current_read_pos;
215 return max(result, 0);
227 return len_available;
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;
235 if (is_clear_with_zero){
236 memset(buffer.data()+current_write_pos,0,buffer.size()-current_write_pos);
243 T *
address()
override {
return buffer.data(); }
246 T *
data() {
return buffer.data()+current_read_pos; }
249 current_read_pos = 0;
250 current_write_pos = 0;
251 if (is_clear_with_zero){
252 memset(buffer.data(),0,buffer.size());
259 size_t result = min(available_size, (
size_t) max_size);
260 current_read_pos = 0;
261 current_write_pos = result;
266 size_t size() {
return max_size; }
268 void resize(
int size) {
269 if (buffer.size() != size) {
278 is_clear_with_zero = flag;
283 int current_read_pos = 0;
284 int current_write_pos = 0;
285 bool owns_buffer =
true;
286 bool is_clear_with_zero =
false;
289 void setWritePos(
int pos) { current_write_pos = pos; }
297 template <
typename T>
306 if (isEmpty())
return -1;
308 T value = _aucBuffer[_iTail];
309 _iTail = nextIndex(_iTail);
317 if (isEmpty())
return -1;
319 return _aucBuffer[_iTail];
322 virtual int peekArray(T*data,
int n){
323 if (isEmpty())
return -1;
325 int count = _numElems;
327 for (
int j=0;j<n;j++){
328 data[j] = _aucBuffer[tail];
329 tail = nextIndex(tail);
340 bool isEmpty() {
return available() == 0; }
346 _aucBuffer[_iHead] = data;
347 _iHead = nextIndex(_iHead);
368 virtual T *
address() {
return _aucBuffer.data(); }
370 virtual void resize(
int len) {
371 if (max_size != len) {
372 LOGI(
"resize: %d", len);
373 _aucBuffer.resize(len);
379 virtual size_t size() {
return max_size; }
388 int nextIndex(
int index) {
return (uint32_t)(index + 1) % max_size; }
401 template <
class File,
typename T>
417 p_file = &bufferFile;
419 LOGE(
"file is not valid");
424 element_count = p_file->size() /
sizeof(T);
425 LOGI(
"existing elements: %s", element_count);
426 read_pos = element_count;
431 if (isEmpty())
return -1;
437 if (auto_rewind && isEmpty()) {
448 if (p_file ==
nullptr)
return 0;
449 int read_count = min(count, element_count);
451 int elements_processed = file_read(data, read_count);
452 read_pos += elements_processed;
453 element_count -= elements_processed;
454 return elements_processed;
459 if (p_file ==
nullptr)
return 0;
460 if (isEmpty())
return -1;
464 size_t count = file_read(&result, 1);
471 bool isEmpty() {
return available() == 0; }
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;
491 if (p_file !=
nullptr) file_seek(0);
506 size_t size()
override {
507 return write_pos - read_pos;
511 File *p_file =
nullptr;
515 int max_size = INT_MAX;
516 bool auto_rewind =
true;
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))
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);
533 int elements_written = bytes_written /
sizeof(T);
534 if (bytes_written != to_write) {
535 LOGE(
"write: %d -> %d", to_write, bytes_written);
537 return elements_written;
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);
558 template <
typename T>
573 result = actual_read_buffer->read();
582 result = actual_read_buffer->peek();
593 if (actual_write_buffer ==
nullptr) {
594 actual_write_buffer = getNextAvailableBuffer();
596 if (actual_write_buffer !=
nullptr) {
597 result = actual_write_buffer->write(data);
599 if (actual_write_buffer->isFull()) {
600 addFilledBuffer(actual_write_buffer);
601 actual_write_buffer = getNextAvailableBuffer();
607 if (start_time == 0l) {
617 if (actual_read_buffer ==
nullptr) {
618 actual_read_buffer = getNextFilledBuffer();
620 if (actual_read_buffer ==
nullptr) {
623 int result = actual_read_buffer->available();
628 actual_read_buffer ==
nullptr ? 0 : actual_read_buffer->available();
635 if (actual_write_buffer ==
nullptr) {
636 actual_write_buffer = getNextAvailableBuffer();
639 if (actual_write_buffer ==
nullptr) {
643 if (actual_write_buffer->isFull()) {
646 addFilledBuffer(actual_write_buffer);
647 actual_write_buffer = getNextAvailableBuffer();
649 return actual_write_buffer->availableForWrite();
655 while (actual_read_buffer !=
nullptr) {
656 actual_read_buffer->reset();
657 addAvailableBuffer(actual_read_buffer);
659 actual_read_buffer = getNextFilledBuffer();
664 unsigned long sampleRate() {
665 unsigned long run_time = (
millis() - start_time);
666 return run_time == 0 ? 0 : sample_count * 1000 / run_time;
671 return actual_read_buffer ==
nullptr ? nullptr
672 : actual_read_buffer->address();
677 if (actual_write_buffer !=
nullptr) {
678 actual_write_buffer->setWritePos(buffer_size);
679 addFilledBuffer(actual_write_buffer);
681 actual_write_buffer = getNextAvailableBuffer();
682 return *actual_write_buffer;
687 BaseBuffer<T> &readEnd() {
690 return *actual_read_buffer;
693 int bufferCountFilled() {
695 for (
int j = 0; j < buffer_count; j++) {
696 if (filled_buffers[j] !=
nullptr) {
703 int bufferCountEmpty() {
705 for (
int j = 0; j < buffer_count; j++) {
706 if (avaliable_buffers[j] !=
nullptr) {
713 void resize(
int size,
int count) {
714 if (buffer_size==size && buffer_count == count)
717 filled_buffers.resize(count);
718 avaliable_buffers.resize(count);
720 write_buffer_count = 0;
721 buffer_count = count;
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);
731 size_t size() {
return buffer_size * buffer_count;}
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;
748 delete actual_write_buffer;
749 actual_write_buffer =
nullptr;
750 delete actual_read_buffer;
751 actual_read_buffer =
nullptr;
753 BaseBuffer<T> *ptr = getNextAvailableBuffer();
754 while (ptr !=
nullptr) {
756 ptr = getNextAvailableBuffer();
759 ptr = getNextFilledBuffer();
760 while (ptr !=
nullptr) {
762 ptr = getNextFilledBuffer();
766 void resetCurrent() {
767 if (actual_read_buffer !=
nullptr) {
768 actual_read_buffer->reset();
769 addAvailableBuffer(actual_read_buffer);
772 actual_read_buffer = getNextFilledBuffer();
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;
787 virtual bool addAvailableBuffer(BaseBuffer<T> *buffer) {
789 for (
int j = 0; j < buffer_count; j++) {
790 if (avaliable_buffers[j] ==
nullptr) {
791 avaliable_buffers[j] = buffer;
799 virtual BaseBuffer<T> *getNextFilledBuffer() {
800 BaseBuffer<T> *result =
nullptr;
801 if (write_buffer_count > 0) {
803 result = filled_buffers[0];
805 for (
int j = 0; j < write_buffer_count - 1; j++)
806 filled_buffers[j] = filled_buffers[j + 1];
808 filled_buffers[write_buffer_count - 1] =
nullptr;
809 write_buffer_count--;
814 virtual bool addFilledBuffer(BaseBuffer<T> *buffer) {
816 if (write_buffer_count < buffer_count) {
817 filled_buffers[write_buffer_count++] = buffer;
833 template <
typename T>
837 LOGI(
"BufferedArray(%d)", len);
842 int16_t *getValues(
size_t offset,
size_t length) {
843 LOGD(
"getValues(%d,%d) - max %d", offset, length, array.size());
850 last_end = actual_end >= 0 ? actual_end : offset;
852 actual_end = offset + length > actual_end ? offset + length : actual_end;
854 int size = actual_end - last_end;
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);
860 assert(offset < actual_end);
861 return &array[offset];
868 Stream *p_stream =
nullptr;