4 #include "AudioTools/CoreAudio/AudioBasic/Collections.h"
5 #include "AudioTools/CoreAudio/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;
150 if (size()==0)
return 0.0;
151 return 100.0 *
static_cast<float>(
available()) /
static_cast<float>(size());
155 void setWritePos(
int pos){};
168 template <
typename T>
188 this->owns_buffer =
false;
189 this->buffer = (uint8_t *)
data;
190 this->current_read_pos = 0;
191 this->current_write_pos = len;
196 if (current_write_pos < buffer.size()) {
197 buffer[current_write_pos++] = sample;
205 if (current_read_pos < current_write_pos) {
206 result = buffer[current_read_pos++];
213 if (current_read_pos < current_write_pos) {
214 result = buffer[current_read_pos];
220 int result = current_write_pos - current_read_pos;
221 return max(result, 0);
233 return len_available;
235 current_read_pos += len;
236 len_available -= len;
237 memmove(buffer.data(), buffer.data()+current_read_pos, len_available);
238 current_read_pos = 0;
239 current_write_pos = len_available;
241 if (is_clear_with_zero){
242 memset(buffer.data()+current_write_pos,0,buffer.size()-current_write_pos);
249 T *
address()
override {
return buffer.data(); }
252 T *
data() {
return buffer.data()+current_read_pos; }
255 current_read_pos = 0;
256 current_write_pos = 0;
257 if (is_clear_with_zero){
258 memset(buffer.data(),0,buffer.size());
265 size_t result = min(available_size, (
size_t) buffer.size());
266 current_read_pos = 0;
267 current_write_pos = result;
272 size_t size() {
return buffer.size(); }
274 void resize(
int size) {
275 if (buffer.size() != size) {
283 is_clear_with_zero = flag;
287 int current_read_pos = 0;
288 int current_write_pos = 0;
289 bool owns_buffer =
true;
290 bool is_clear_with_zero =
false;
293 void setWritePos(
int pos) { current_write_pos = pos; }
301 template <
typename T>
310 if (isEmpty())
return -1;
312 T value = _aucBuffer[_iTail];
313 _iTail = nextIndex(_iTail);
321 if (isEmpty())
return -1;
323 return _aucBuffer[_iTail];
326 virtual int peekArray(T*data,
int n){
327 if (isEmpty())
return -1;
329 int count = _numElems;
331 for (
int j=0;j<n;j++){
332 data[j] = _aucBuffer[tail];
333 tail = nextIndex(tail);
344 bool isEmpty() {
return available() == 0; }
350 _aucBuffer[_iHead] = data;
351 _iHead = nextIndex(_iHead);
372 virtual T *
address() {
return _aucBuffer.data(); }
374 virtual void resize(
int len) {
375 if (max_size != len) {
376 LOGI(
"resize: %d", len);
377 _aucBuffer.resize(len);
383 virtual size_t size() {
return max_size; }
392 int nextIndex(
int index) {
return (uint32_t)(index + 1) % max_size; }
405 template <
class File,
typename T>
421 p_file = &bufferFile;
423 LOGE(
"file is not valid");
428 element_count = p_file->size() /
sizeof(T);
429 LOGI(
"existing elements: %s", element_count);
430 read_pos = element_count;
435 if (isEmpty())
return -1;
441 if (auto_rewind && isEmpty()) {
452 if (p_file ==
nullptr)
return 0;
453 int read_count = min(count, element_count);
455 int elements_processed = file_read(data, read_count);
456 read_pos += elements_processed;
457 element_count -= elements_processed;
458 return elements_processed;
463 if (p_file ==
nullptr)
return 0;
464 if (isEmpty())
return -1;
468 size_t count = file_read(&result, 1);
475 bool isEmpty() {
return available() == 0; }
482 if (p_file ==
nullptr)
return 0;
483 file_seek(write_pos);
484 int elements_written = file_write(data, len);
485 write_pos += elements_written;
486 element_count += elements_written;
487 return elements_written;
495 if (p_file !=
nullptr) file_seek(0);
510 size_t size()
override {
511 return write_pos - read_pos;
515 File *p_file =
nullptr;
519 int max_size = INT_MAX;
520 bool auto_rewind =
true;
522 void file_seek(
int pos) {
523 if (p_file->position() != pos *
sizeof(T)) {
524 LOGD(
"file_seek: %d", pos);
525 if (!p_file->seek(pos *
sizeof(T))) {
526 LOGE(
"seek %d", pos *
sizeof(T))
531 int file_write(
const T *data,
int count) {
532 LOGD(
"file_write: %d", count);
533 if (p_file ==
nullptr)
return 0;
534 int to_write =
sizeof(T) * count;
535 int bytes_written = p_file->write((
const uint8_t *)data, to_write);
537 int elements_written = bytes_written /
sizeof(T);
538 if (bytes_written != to_write) {
539 LOGE(
"write: %d -> %d", to_write, bytes_written);
541 return elements_written;
544 int file_read(T *result,
int count) {
545 LOGD(
"file_read: %d", count);
546 size_t result_bytes = p_file->read((uint8_t *)result,
sizeof(T) * count);
547 if (result_bytes != count *
sizeof(T)) {
548 LOGE(
"readBytes: %d -> %d", (
int)
sizeof(T) * count, (
int)result_bytes);
562 template <
typename T>
577 result = actual_read_buffer->read();
586 result = actual_read_buffer->peek();
597 if (actual_write_buffer ==
nullptr) {
598 actual_write_buffer = getNextAvailableBuffer();
600 if (actual_write_buffer !=
nullptr) {
601 result = actual_write_buffer->write(data);
603 if (actual_write_buffer->isFull()) {
604 addFilledBuffer(actual_write_buffer);
605 actual_write_buffer = getNextAvailableBuffer();
611 if (start_time == 0l) {
622 if (actual_read_buffer ==
nullptr) {
623 actual_read_buffer = getNextFilledBuffer();
625 if (actual_read_buffer ==
nullptr) {
628 int result = actual_read_buffer->available();
632 result = (actual_read_buffer ==
nullptr) ? 0 : actual_read_buffer->available();
639 if (actual_write_buffer ==
nullptr) {
640 actual_write_buffer = getNextAvailableBuffer();
643 if (actual_write_buffer ==
nullptr) {
647 if (actual_write_buffer->isFull()) {
650 addFilledBuffer(actual_write_buffer);
651 actual_write_buffer = getNextAvailableBuffer();
653 return actual_write_buffer->availableForWrite();
659 while (actual_read_buffer !=
nullptr) {
660 actual_read_buffer->reset();
661 addAvailableBuffer(actual_read_buffer);
663 actual_read_buffer = getNextFilledBuffer();
668 unsigned long sampleRate() {
669 unsigned long run_time = (
millis() - start_time);
670 return run_time == 0 ? 0 : sample_count * 1000 / run_time;
675 return actual_read_buffer ==
nullptr ? nullptr
676 : actual_read_buffer->address();
681 if (actual_write_buffer !=
nullptr) {
682 actual_write_buffer->setWritePos(buffer_size);
683 addFilledBuffer(actual_write_buffer);
685 actual_write_buffer = getNextAvailableBuffer();
686 return *actual_write_buffer;
691 BaseBuffer<T> &readEnd() {
694 return *actual_read_buffer;
697 virtual int bufferCountFilled() {
698 return filled_buffers.size();
701 virtual int bufferCountEmpty() {
702 return available_buffers.size();
705 virtual void resize(
int size,
int count) {
706 if (buffer_size==size && buffer_count == count)
709 filled_buffers.resize(count);
710 available_buffers.resize(count);
714 buffer_count = count;
716 for (
int j = 0; j < count; j++) {
717 BaseBuffer<T>* buffer =
new SingleBuffer<T>(size);
718 LOGD(
"new buffer %p", buffer);
719 available_buffers.enqueue(buffer);
723 size_t size() {
return buffer_size * buffer_count;}
727 uint16_t buffer_count = 0;
728 BaseBuffer<T> *actual_read_buffer =
nullptr;
729 BaseBuffer<T> *actual_write_buffer =
nullptr;
730 QueueFromVector<BaseBuffer<T> *> available_buffers{0,
nullptr};
731 QueueFromVector<BaseBuffer<T> *> filled_buffers{0,
nullptr};
734 unsigned long start_time = 0;
735 unsigned long sample_count = 0;
741 if (actual_write_buffer){
742 LOGD(
"deleting %p", actual_write_buffer);
743 delete actual_write_buffer;
744 actual_write_buffer =
nullptr;
746 if (actual_read_buffer){
747 LOGD(
"deleting %p", actual_read_buffer);
748 delete actual_read_buffer;
749 actual_read_buffer =
nullptr;
752 BaseBuffer<T> *ptr = getNextAvailableBuffer();
753 while (ptr !=
nullptr) {
754 LOGD(
"deleting %p", ptr);
756 ptr = getNextAvailableBuffer();
759 ptr = getNextFilledBuffer();
760 while (ptr !=
nullptr) {
761 LOGD(
"deleting %p", ptr);
763 ptr = getNextFilledBuffer();
767 void resetCurrent() {
768 if (actual_read_buffer !=
nullptr) {
769 actual_read_buffer->reset();
770 addAvailableBuffer(actual_read_buffer);
773 actual_read_buffer = getNextFilledBuffer();
776 virtual BaseBuffer<T> *getNextAvailableBuffer() {
777 if (available_buffers.empty())
return nullptr;
778 BaseBuffer<T> *result =
nullptr;
779 available_buffers.dequeue(result);
783 virtual bool addAvailableBuffer(BaseBuffer<T> *buffer) {
784 return available_buffers.enqueue(buffer);
787 virtual BaseBuffer<T> *getNextFilledBuffer() {
788 if (filled_buffers.empty())
return nullptr;
789 BaseBuffer<T> *result =
nullptr;
790 filled_buffers.dequeue(result);
794 virtual bool addFilledBuffer(BaseBuffer<T> *buffer) {
795 return filled_buffers.enqueue(buffer);
808 template <
typename T>
812 LOGI(
"BufferedArray(%d)", len);
817 int16_t *getValues(
size_t offset,
size_t length) {
818 LOGD(
"getValues(%d,%d) - max %d", offset, length, array.size());
825 last_end = actual_end >= 0 ? actual_end : offset;
827 actual_end = offset + length > actual_end ? offset + length : actual_end;
829 int size = actual_end - last_end;
831 LOGD(
"readBytes(%d,%d)", last_end, size);
832 assert(last_end + size <= array.size());
833 p_stream->readBytes((uint8_t *)(&array[last_end]), size * 2);
835 assert(offset < actual_end);
836 return &array[offset];
843 Stream *p_stream =
nullptr;