arduino-audio-tools
Loading...
Searching...
No Matches
AudioStreams.h
Go to the documentation of this file.
1#pragma once
2#include "AudioToolsConfig.h"
11
12#ifndef IRAM_ATTR
13#define IRAM_ATTR
14#endif
15
16namespace audio_tools {
17
24 public:
26 TRACED();
27 p_stream = &s;
28 p_stream->setTimeout(clientTimeout);
29 }
30
31 virtual bool begin() { return true; }
32 virtual void end() {}
33
34 virtual size_t readBytes(uint8_t *data, size_t len) {
35 // Serial.print("Timeout audiostream: ");
36 // Serial.println(p_stream->getTimeout());
37 return p_stream->readBytes(data, len);
38 }
39
40 int read() { return p_stream->read(); }
41
42 int peek() { return p_stream->peek(); }
43
44 int available() { return p_stream->available(); }
45
46 virtual size_t write(uint8_t c) { return p_stream->write(c); }
47
48 virtual size_t write(const uint8_t *data, size_t len) {
49 return p_stream->write(data, len);
50 }
51
52 virtual int availableForWrite() { return p_stream->availableForWrite(); }
53
54 virtual void flush() { p_stream->flush(); }
55
56 protected:
59};
60
69 public:
71 virtual void setStream(Stream &in) = 0;
73 virtual void setOutput(Print &out) = 0;
74
76 virtual void setStream(AudioStream &io) {
77 setStream(static_cast<Stream&>(io));
79 }
80
82 virtual void setOutput(AudioOutput &out) {
83 setOutput(static_cast<Print&>(out));
85 }
86};
87
95class MemoryStream : public AudioStream {
96 public:
97 // Default constructor
98 MemoryStream() = default;
101 LOGD("MemoryStream: %d", buffer_size);
102 this->buffer_size = buffer_size;
103 this->memory_type = memoryType;
104 resize(buffer_size);
105 info.clear(); // mark audio info as unknown
106 }
107
110 MemoryStream(const uint8_t *buffer, int buffer_size, bool isActive = true,
112 LOGD("MemoryStream: %d", buffer_size);
113 owns_memory = false;
115 is_active = isActive;
116 info.clear(); // mark audio info as unknown
117 }
118
120 MemoryStream(MemoryStream &source) : AudioStream() { copy(source); }
121
124 setValue(source.buffer, source.buffer_size, source.memory_type);
125 // clear source data
126 source.setValue(nullptr, 0, source.memory_type);
127 }
128
130 TRACED();
131 if (memoryCanChange() && owns_memory && buffer != nullptr) free(buffer);
132 }
133
136 copy(other);
137 return *this;
138 }
139
141 operator bool() override { return available() > 0; }
142
145 this->info = info;
146 return begin();
147 }
148
150 bool begin() override {
151 TRACED();
153 if (this->buffer == nullptr && owns_memory && memoryCanChange()) {
155 }
156 read_pos = 0;
157 is_active = this->buffer != nullptr;
158 return is_active;
159 }
160
162 void rewind() {
163 if (buffer != nullptr && buffer_size > 0) {
164 read_pos = 0;
165 }
166 }
167
168 virtual size_t write(uint8_t byte) override {
169 if (!is_active) return 0;
170 if (memory_type == FLASH_RAM) return 0;
171 if (buffer == nullptr) return 0;
172 int result = 0;
173 if (write_pos < buffer_size) {
174 result = 1;
176 write_pos++;
177 }
178 return result;
179 }
180
181 virtual size_t write(const uint8_t *data, size_t len) override {
182 if (!is_active) return 0;
183 if (memory_type == FLASH_RAM) return 0;
184 size_t result = 0;
185 for (size_t j = 0; j < len; j++) {
186 if (!write(data[j])) {
187 break;
188 }
189 result = j + 1;
190 }
191 return result;
192 }
193
194 virtual int available() override {
195 if (!is_active) return 0;
196 if (buffer == nullptr) return 0;
197 int result = write_pos - read_pos;
198 if (result <= 0 && is_loop) {
199 // rewind to start
201 result = write_pos - read_pos;
202 // call callback
203 if (rewind_cb != nullptr) rewind_cb();
204 }
205 return is_loop ? DEFAULT_BUFFER_SIZE : result;
206 }
207
208 virtual int availableForWrite() override {
209 if (!is_active) return 0;
210 if (memory_type == FLASH_RAM) return 0;
211 return buffer_size - write_pos;
212 }
213
214 virtual int read() override {
215 int result = peek();
216 if (result >= 0) {
217 read_pos++;
218 }
219 return result;
220 }
221
222 virtual size_t readBytes(uint8_t *data, size_t len) override {
223 if (!is_active) return 0;
224 size_t count = 0;
225 while (count < len) {
226 int c = read();
227 if (c < 0) break;
228 *data++ = (char)c;
229 count++;
230 }
231 return count;
232 }
233
234 virtual int peek() override {
235 if (!is_active) return -1;
236 int result = -1;
237 if (available() > 0) {
238 result = buffer[read_pos];
239 }
240 return result;
241 }
242
243 virtual void flush() override {}
244
245 virtual void end() override {
246 read_pos = 0;
247 is_active = false;
248 }
249
251 virtual void clear(bool reset = false) {
252 if (memoryCanChange()) {
253 write_pos = 0;
254 read_pos = 0;
255 if (owns_memory && buffer == nullptr) {
257 }
258 if (reset) {
259 // we clear the buffer data
261 }
262 } else {
263 read_pos = 0;
264 LOGW("data is read only");
265 }
266 }
267
270 virtual void setLoop(bool loop) {
271 is_loop = loop;
272 rewind_pos = 0;
273 if (buffer != nullptr && buffer_size > 12) {
274 if (memcmp("WAVE", buffer + 8, 4) == 0) {
275 rewind_pos = 44;
276 }
277 }
278 }
279
281 virtual void setLoop(bool loop, int rewindPos) {
282 is_loop = loop;
284 }
285
288 virtual bool resize(size_t size) {
289 if (!memoryCanChange()) return false;
290 if (!owns_memory) return false;
291
292 buffer_size = size;
293 switch (memory_type) {
294#if defined(USE_PSRAM) && defined(ARDUINO)
295 case PS_RAM:
296 buffer = (buffer == nullptr) ? (uint8_t *)ps_calloc(size, 1)
297 : (uint8_t *)ps_realloc(buffer, size);
298 break;
299#endif
300 default:
301 buffer = (buffer == nullptr) ? (uint8_t *)calloc(size, 1)
302 : (uint8_t *)realloc(buffer, size);
303 break;
304 }
305 return buffer != nullptr;
306 }
307
309 virtual uint8_t *data() { return buffer; }
310
312 virtual bool setAvailable(size_t len) {
313 if (len <= buffer_size) {
314 write_pos = len;
316 return true;
317 }
318 return false;
319 }
320
322 void setRewindCallback(void (*cb)()) { this->rewind_cb = cb; }
323
327 this->buffer_size = buffer_size;
328 this->read_pos = 0;
329 this->write_pos = buffer_size;
330 this->buffer = (uint8_t *)buffer;
331 this->memory_type = memoryType;
332 }
333
334 protected:
335 int write_pos = 0;
336 int read_pos = 0;
337 int buffer_size = 0;
338 int rewind_pos = 0;
339 uint8_t *buffer = nullptr;
341 bool is_loop = false;
342 void (*rewind_cb)() = nullptr;
343 bool is_active = false;
344 bool owns_memory = true;
345
347
348 void copy(MemoryStream &source) {
349 if (this == &source) return;
350
351 // Release currently owned mutable buffer.
352 if (memoryCanChange() && owns_memory && buffer != nullptr) {
353 free(buffer);
354 buffer = nullptr;
355 }
356
357 // Shallow copy for FLASH memory source.
358 if (source.memory_type == FLASH_RAM) {
359 owns_memory = false;
360 setValue(source.buffer, source.buffer_size, source.memory_type);
361 is_active = source.is_active;
362 is_loop = source.is_loop;
363 rewind_pos = source.rewind_pos;
364 return;
365 }
366
367 // Deep copy for mutable source memory.
368 owns_memory = true;
369 setValue(nullptr, source.buffer_size, source.memory_type);
370 if (!resize(source.buffer_size)) {
371 setValue(nullptr, 0, source.memory_type);
372 is_active = false;
373 return;
374 }
375
376 if (source.buffer != nullptr && source.buffer_size > 0) {
377 memcpy(buffer, source.buffer, source.buffer_size);
378 }
379
380 write_pos = source.write_pos;
381 read_pos = source.read_pos;
384
385 is_active = source.is_active;
386 is_loop = source.is_loop;
387 rewind_pos = source.rewind_pos;
388 }
389};
390
399 public:
401
402 virtual int available() override {
403 // LOGD("RingBufferStream::available: %zu",buffer->available());
404 return buffer.available();
405 }
406
407 virtual int availableForWrite() override {
408 return buffer.availableForWrite();
409 }
410
411 virtual void flush() override {}
412 virtual int peek() override {
413 uint8_t data = 0;
414 if (!buffer.peek(data)) return -1;
415 return data;
416 }
417 virtual int read() override {
418 uint8_t data = 0;
419 if (!buffer.read(data)) return -1;
420 return data;
421 }
422
423 virtual size_t readBytes(uint8_t *data, size_t len) override {
424 return buffer.readArray(data, len);
425 }
426
427 virtual size_t write(const uint8_t *data, size_t len) override {
428 // LOGD("RingBufferStream::write: %zu",len);
429 return buffer.writeArray(data, len);
430 }
431
432 virtual size_t write(uint8_t c) override { return buffer.write(c); }
433
434 void resize(int size) { buffer.resize(size); }
435
436 size_t size() { return buffer.size(); }
437
438 protected:
440};
441
453template <class T = int16_t>
455 public:
457
459 TRACED();
460 setInput(generator);
461 }
462
463 void setInput(SoundGenerator<T> &generator) {
464 this->p_generator = &generator;
465 }
466
468 if (p_generator == nullptr) {
470 return AudioInfo();
471 }
472 return this->p_generator->defaultConfig();
473 }
474
476 if (newInfo.bits_per_sample != sizeof(T) * 8) {
477 LOGE("Wrong bits_per_sample: %d", newInfo.bits_per_sample);
478 }
479 if (p_generator != nullptr) {
481 }
483 }
484
486 bool begin() override {
487 TRACED();
488 if (p_generator == nullptr) {
490 return false;
491 }
494 active = true;
495 return active;
496 }
497
499 bool begin(AudioInfo cfg) {
500 TRACED();
501 if (p_generator == nullptr) {
503 return false;
504 }
505 p_generator->begin(cfg);
507 active = true;
508 return active;
509 }
510
512 void end() override {
513 TRACED();
514 if (p_generator != nullptr) {
515 p_generator->end();
516 }
517 active = true; // legacy support - most sketches do not call begin
518 }
519
520 AudioInfo audioInfo() override {
521 if (p_generator == nullptr) {
523 return AudioStream::audioInfo();
524 }
525 return p_generator->audioInfo();
526 }
527
529 virtual int available() override { return active ? buffer_size : 0; }
530
532 size_t readBytes(uint8_t *data, size_t len) override {
533 if (!active) return 0;
534 if (p_generator == nullptr) {
535 return 0;
536 }
537 LOGD("GeneratedSoundStream::readBytes: %u", (unsigned int)len);
538 return p_generator->readBytes(data, len);
539 }
540
541 bool isActive() {
542 if (p_generator == nullptr) return false;
543 return active && p_generator->isActive();
544 }
545
546 operator bool() override { return isActive(); }
547
548 void flush() override {}
549
552
553 protected:
554 bool active = true; // support for legacy sketches
557 DEFAULT_BUFFER_SIZE * 100; // there is no reason to limit this
558 const char *source_not_defined_error = "Source not defined";
559};
560
570 public:
571 BufferedStream(size_t buffer_size) {
572 TRACED();
573 if (buffer_size > 0) resize(buffer_size);
574 }
575
576 BufferedStream(Print &out, size_t buffer_size = 1024) {
577 TRACED();
578 setOutput(out);
579 if (buffer_size > 0) resize(buffer_size);
580 }
581
582 BufferedStream(Stream &io, size_t buffer_size = 1024) {
583 TRACED();
584 setStream(io);
585 if (buffer_size > 0) resize(buffer_size);
586 }
587
588 BufferedStream(size_t buffer_size, Print &out) {
589 TRACED();
590 setOutput(out);
591 if (buffer_size > 0) resize(buffer_size);
592 }
593
594 BufferedStream(size_t buffer_size, Stream &io) {
595 TRACED();
596 setStream(io);
597 if (buffer_size > 0) resize(buffer_size);
598 }
599
600 void setOutput(Print &out) override { p_out = &out; }
601 void setStream(Print &out) { setOutput(out); }
602 void setStream(Stream &io) override {
603 p_in = &io;
604 p_out = &io;
605 }
606
608 size_t write(uint8_t c) override {
609 if (buffer.isFull()) {
610 flush();
611 }
612 return buffer.write(c);
613 }
614
616 size_t write(const uint8_t *data, size_t len) override {
617 LOGD("%s: %zu", LOG_METHOD, len);
618 int result = 0;
619 for (int j = 0; j < len; j++) {
620 result += write(data[j]);
621 }
622 return result;
623 }
624
626 void flush() override {
627 // just dump the memory of the buffer and clear it
628 if (buffer.available() > 0) {
630 buffer.reset();
631 }
632 }
633
635 int read() override {
636 if (buffer.isEmpty()) {
637 refill();
638 }
639 uint8_t result = 0;
640 if (!buffer.read(result)) return -1;
641 return result;
642 }
643
645 int peek() override {
646 if (buffer.isEmpty()) {
647 refill();
648 }
649 uint8_t result = 0;
650 if (!buffer.peek(result)) return -1;
651 return result;
652 };
653
655 size_t readBytes(uint8_t *data, size_t len) override {
656 if (buffer.isEmpty() && len >= minReadBufferSize) {
657 return readExt(data, len);
658 } else {
659 refill(len);
660 return buffer.readArray(data, len);
661 }
662 }
663
665 size_t peekBytes(uint8_t *data, size_t len) {
666 if (buffer.isEmpty()) {
667 refill();
668 }
669 return buffer.peekArray(data, len);
670 }
671
673 int available() override {
674 if (p_in == nullptr) return 0;
675 return buffer.available() + p_in->available();
676 }
677
679 void clear() { buffer.reset(); }
680
682 void resize(int size) { buffer.resize(size); }
683
686 void setMinUnbufferedReadSize(size_t size) { minReadBufferSize = size; }
687
688 protected:
690 Print *p_out = nullptr;
691 Stream *p_in = nullptr;
692 size_t minReadBufferSize = 1024;
693
695 void refill() {
696 // Preserve any existing unread data then append new bytes
697 buffer.trim();
700 if (free_space == 0) {
701 // Buffer full – nothing we can append
702 return;
703 }
704 // Read new data directly behind existing bytes
707 }
708
710 void refill(size_t len) {
711 if (buffer.available() >= len) return;
712 refill();
713 }
714
715 virtual size_t writeExt(const uint8_t *data, size_t len) {
716 return p_out == nullptr ? 0 : p_out->write(data, len);
717 }
718 virtual size_t readExt(uint8_t *data, size_t len) {
719 return p_in == nullptr ? 0 : p_in->readBytes(data, len);
720 }
721};
722
731template <typename T = int16_t>
733 public:
734 ConverterStream() = default;
735
736 ConverterStream(BaseConverter &converter) { setConverter(converter); }
737
738 ConverterStream(Stream &stream, BaseConverter &converter) {
739 setConverter(converter);
740 setStream(stream);
741 }
742
744 setConverter(converter);
745 setOutput(out);
746 }
747
748 void setStream(Stream &stream) {
749 TRACEI();
750 p_stream = &stream;
751 p_out = &stream;
752 }
753
754 void setOutput(Print &out) {
755 TRACEI();
756 p_out = &out;
757 }
758
760
761 virtual int availableForWrite() { return p_out->availableForWrite(); }
762
763 virtual size_t write(const uint8_t *data, size_t len) {
764 size_t result = p_converter->convert((uint8_t *)data, len);
765 if (result > 0) {
766 size_t result_written = p_out->write(data, result);
767 return len * result_written / result;
768 }
769 return 0;
770 }
771
772 size_t readBytes(uint8_t *data, size_t len) override {
773 if (p_stream == nullptr) return 0;
774 size_t result = p_stream->readBytes(data, len);
775 return p_converter->convert(data, result);
776 }
777
779 virtual int available() override {
780 if (p_stream == nullptr) return 0;
781 return p_stream->available();
782 }
783
784 protected:
785 Stream *p_stream = nullptr;
786 Print *p_out = nullptr;
788};
789
797 public:
798 MeasuringStream(int count = 10, Print *logOut = nullptr) {
799 this->count = count;
800 this->max_count = count;
801 p_stream = &null;
802 p_print = &null;
803 start_time = millis();
805 }
806
807 MeasuringStream(Print &print, int count = 10, Print *logOut = nullptr) {
808 this->count = count;
809 this->max_count = count;
810 setOutput(print);
811 start_time = millis();
813 }
814
815 MeasuringStream(Stream &stream, int count = 10, Print *logOut = nullptr) {
816 this->count = count;
817 this->max_count = count;
818 setStream(stream);
819 start_time = millis();
821 }
822
824 void setLogOutput(Print &out) { p_logout = &out; }
825
827 void setStream(Stream &io) override {
828 p_print = &io;
829 p_stream = &io;
830 };
831
833 void setOutput(Print &out) override { p_print = &out; }
834
836 size_t readBytes(uint8_t *data, size_t len) override {
838 return measure(p_stream->readBytes(data, len));
839 }
840
841 int available() override { return p_stream->available(); }
842
844 virtual size_t write(const uint8_t *data, size_t len) override {
846 return measure(p_print->write(data, len));
847 }
848
850 virtual int availableForWrite() override {
851 return p_print->availableForWrite();
852 }
853
856
859 if (frame_size == 0) return 0;
861 }
862
865
866 void setAudioInfo(AudioInfo info) override {
867 LOGI("MeasuringStream::setAudioInfo: %d bits, %d channels", info.bits_per_sample, info.channels);
870 }
871
872 bool begin() override {
875 return ModifyingStream::begin();
876 }
877
880 return begin();
881 }
882
884 void setFrameSize(int size) { frame_size = size; }
885
888
889 void setName(const char *name) { this->name = name; }
890
893
896
899 if (bytesSinceBegin() == 0) return 0;
900 return static_cast<float>(timeSinceBegin()) / bytesSinceBegin() *
901 totalBytes;
902 }
903
906 if (bytesSinceBegin() == 0) return 0;
907 return estimatedTotalTimeFor(totalBytes) - timeSinceBegin();
908 }
909
913 bool is_regular_update = true;
914 if (pos < total_bytes_since_begin) {
915 begin();
916 is_regular_update = false;
917 }
919 return is_regular_update;
920 }
921
922 protected:
923 int max_count = 0;
924 int count = 0;
925 Stream *p_stream = nullptr;
926 Print *p_print = nullptr;
928 int total_bytes = 0;
930 int frame_size = 0;
932 Print *p_logout = nullptr;
933 bool report_bytes = false;
934 const char *name = "";
937
938 size_t measure(size_t len) {
939 count--;
940 total_bytes += len;
941
942 if (count <= 0) {
944 int time_diff = end_time - start_time; // in ms
945 if (time_diff > 0) {
947 printResult();
949 total_bytes = 0;
951 }
952 }
953 return len;
954 }
955
956 void printResult() {
957 char msg[70];
958 if (report_bytes || frame_size == 0) {
959 snprintf(msg, 70, "%s ==> Bytes per second: %d", name, bytes_per_second);
960 } else {
961 snprintf(msg, 70, "%s ==> Samples per second: %d", name,
963 }
964 if (p_logout != nullptr) {
965 p_logout->println(msg);
966 } else {
967 LOGI("%s", msg);
968 }
969 }
970};
971
979 public:
980 size_t total_size = 0;
981};
990 public:
991 ProgressStream() = default;
992
993 ProgressStream(Print &print) { setPrint(print); }
994
995 ProgressStream(Stream &stream) { setStream(stream); }
996
998 setStream(stream);
999 p_info_from = &stream;
1000 }
1001
1003
1008
1009 void setStream(Stream &stream) override {
1010 p_stream = &stream;
1011 p_print = &stream;
1012 }
1013
1014 void setStream(Print &print) { p_print = &print; }
1015
1016 void setPrint(Print &print) { p_print = &print; }
1017
1018 bool begin() override {
1019 if (p_info_from != nullptr) {
1021 }
1022 return AudioStream::begin();
1023 }
1024
1027 bool begin(size_t len) {
1028 setSize(len);
1029 return begin();
1030 }
1031
1035 return begin();
1036 }
1037
1039 void setSize(size_t len) {
1040 total_processed = 0;
1042 }
1043
1045 size_t size() { return progress_info.total_size; }
1046
1048 size_t processedBytes() { return total_processed; }
1049
1051 size_t processedSecs() { return total_processed / byteRate(); }
1052
1055
1057 size_t totalSecs() { return totalBytes() / byteRate(); }
1058
1060 float percentage() {
1061 if (progress_info.total_size == 0) return 0;
1062 return 100.0 * total_processed / progress_info.total_size;
1063 }
1064
1066 size_t readBytes(uint8_t *data, size_t len) override {
1067 if (p_stream == nullptr) return 0;
1068 return measure(p_stream->readBytes(data, len));
1069 }
1070
1071 int available() override {
1072 if (p_stream == nullptr) return 0;
1073 return p_stream->available();
1074 }
1075
1077 virtual size_t write(const uint8_t *data, size_t len) override {
1078 if (p_print == nullptr) return 0;
1079 return measure(p_print->write(data, len));
1080 }
1081
1083 virtual int availableForWrite() override {
1084 if (p_print == nullptr) return 0;
1085 return p_print->availableForWrite();
1086 }
1087
1088 protected:
1090 Stream *p_stream = nullptr;
1091 Print *p_print = nullptr;
1094
1095 size_t measure(size_t len) {
1096 total_processed += len;
1097 return len;
1098 }
1099
1100 size_t byteRate() {
1102 int byte_rate = info.sample_rate * info.bits_per_sample * info.channels / 8;
1103 if (byte_rate == 0) {
1104 LOGE("Audio Info not defined");
1105 return 0;
1106 }
1107 return byte_rate;
1108 }
1109};
1110
1116struct ThrottleConfig : public AudioInfo {
1118 sample_rate = 44100;
1119 bits_per_sample = 16;
1120 channels = 2;
1121 }
1123};
1124
1132 public:
1133 Throttle() = default;
1134 Throttle(Print &out) { setOutput(out); }
1136
1138 void setStream(Stream &io) override {
1139 p_out = &io;
1140 p_in = &io;
1141 };
1142
1144 void setOutput(Print &out) override { p_out = &out; }
1145
1148 return c;
1149 }
1150
1152 LOGI("begin sample_rate: %d, channels: %d, bits: %d", (int)info.sample_rate,
1153 (int)info.channels, (int)info.bits_per_sample);
1154 this->info = cfg;
1155 this->cfg = cfg;
1156 return begin();
1157 }
1158
1160 LOGI("begin sample_rate: %d, channels: %d, bits: %d", (int)info.sample_rate,
1161 (int)info.channels, (int)info.bits_per_sample);
1162 this->info = info;
1163 this->cfg.copyFrom(info);
1164 return begin();
1165 }
1166
1167 bool begin() override {
1169 startDelay();
1170 return true;
1171 }
1172
1173 // (re)starts the timing
1174 void startDelay() {
1175 start_time = micros();
1176 sum_frames = 0;
1177 }
1178
1179 int availableForWrite() override {
1180 if (p_out) {
1181 return p_out->availableForWrite();
1182 }
1183 return DEFAULT_BUFFER_SIZE;
1184 }
1185
1186 size_t write(const uint8_t *data, size_t len) override {
1187 size_t result = p_out->write(data, len);
1188 delayBytes(len);
1189 return result;
1190 }
1191
1192 int available() override {
1193 if (p_in == nullptr) return 0;
1194 return p_in->available();
1195 }
1196
1197 size_t readBytes(uint8_t *data, size_t len) override {
1198 if (p_in == nullptr) {
1199 delayBytes(len);
1200 return 0;
1201 }
1202 size_t result = p_in->readBytes(data, len);
1203 delayBytes(len);
1204 return result;
1205 }
1206
1207 // delay
1208 void delayBytes(size_t bytes) { delayFrames(bytes / frame_size); }
1209
1210 // delay
1211 void delayFrames(size_t frames) {
1212 sum_frames += frames;
1216 LOGD("wait us: %ld", static_cast<long>(waitUs));
1217 if (waitUs > 0) {
1218 int64_t waitMs = waitUs / 1000;
1219 if (waitMs > 0) delay(waitMs);
1220 delayMicroseconds(waitUs - (waitMs * 1000));
1221 } else {
1222 LOGD("negative delay!")
1223 }
1224 }
1225
1226 inline int64_t getDelayUs(uint64_t frames) {
1227 return (frames * 1000000) / cfg.sample_rate;
1228 }
1229
1230 inline int64_t getDelayMs(uint64_t frames) {
1231 return getDelayUs(frames) / 1000;
1232 }
1233
1235 return getDelayUs(frames) / 1000000l;
1236 }
1237
1238 protected:
1242 int frame_size = 0;
1243 Print *p_out = nullptr;
1244 Stream *p_in = nullptr;
1245};
1246
1256template <typename T=int16_t, typename SumT=float>
1257class InputMixer : public AudioStream {
1258 public:
1259 InputMixer() = default;
1260
1262 int add(Stream &in, int weight = 100) {
1263 streams.push_back(&in);
1264 weights.push_back(weight);
1266 return streams.indexOf(&in);
1267 }
1268
1270 bool set(int index, Stream &in) {
1271 if (index < size()) {
1272 streams[index] = &in;
1273 return true;
1274 } else {
1275 LOGE("Invalid index %d - max is %d", index, size() - 1);
1276 return false;
1277 }
1278 }
1279
1280 virtual bool begin(AudioInfo info) {
1283 LOGI("frame_size: %d", frame_size);
1284 return frame_size > 0;
1285 }
1286
1290 void setWeight(int index, int weight) {
1291 if (index < streams.size()) {
1292 weights[index] = weight;
1294 } else {
1295 LOGE("Invalid index %d - max is %d", index, size() - 1);
1296 }
1297 }
1298
1300 void end() override {
1301 streams.clear();
1302 weights.clear();
1303 gains.clear();
1304 result_vect.clear();
1305 current_vect.clear();
1306 total_weights = 0.0;
1307 }
1308
1310 int size() { return streams.size(); }
1311
1313 size_t readBytes(uint8_t *data, size_t len) override {
1314 if (total_weights == 0 || frame_size == 0 || len == 0) {
1315 LOGW("readBytes: %d", (int)len);
1316 return 0;
1317 }
1318
1320 len = min((int)len, availableBytes());
1321 }
1322
1323 int result_len = 0;
1324
1325 if (len > 0) {
1326 // result_len must be full frames
1327 result_len = (len / frame_size) * frame_size;;
1328 // replace sample based with vector based implementation
1329 // readBytesSamples((T*)data, result_len));
1331 }
1332 return result_len;
1333 }
1334
1338
1342
1344 bool remove(int idx) {
1345 if (idx < 0 || idx >= size()) {
1346 return false;
1347 }
1348 streams.erase(idx);
1349 weights.erase(idx);
1351 return true;
1352 }
1353
1355 bool remove() {
1356 bool rc = false;
1357 int idx = nextEmptyIndex();
1358 while (idx >= 0) {
1359 rc = true;
1360 streams.erase(idx);
1361 weights.erase(idx);
1362 idx = nextEmptyIndex();
1363 }
1365 return rc;
1366 }
1367
1369 int indexOf(Stream &stream) { return streams.indexOf(&stream); }
1370
1372 Stream *operator[](int idx) {
1373 if (idx < 0 || idx >= size()) return nullptr;
1374 return streams[idx];
1375 }
1376
1379 for (int i = 0; i < streams.size(); i++) {
1380 if (streams[i]->available() == 0) {
1381 return i;
1382 }
1383 }
1384 return -1;
1385 }
1386
1387 protected:
1392 int frame_size = 4;
1397
1400 int total = 0;
1401 for (int j = 0; j < weights.size(); j++) {
1402 total += weights[j];
1403 }
1404 total_weights = total;
1406 for (int j = 0; j < weights.size(); j++) {
1407 gains[j] = total_weights == 0 ? 0.0f : static_cast<float>(weights[j]) / total_weights;
1408 }
1409 }
1410
1412 int readBytesVector(T *p_data, int byteCount) {
1413 int samples = byteCount / sizeof(T);
1414 if (result_vect.size() < samples) result_vect.resize(samples);
1415 if (current_vect.size() < samples) current_vect.resize(samples);
1416 int stream_count = size();
1417 resultClear(samples);
1418 int samples_eff_max = 0;
1419 for (int j = 0; j < stream_count; j++) {
1420 if (weights[j] > 0) {
1421 int samples_eff =
1425 }
1426 }
1427 // copy result
1428 for (int j = 0; j < samples_eff_max; j++) {
1429 p_data[j] = static_cast<T>(result_vect[j]);
1430 }
1431 return samples_eff_max * sizeof(T);
1432 }
1433
1436 int result = DEFAULT_BUFFER_SIZE;
1437 for (int j = 0; j < size(); j++) {
1438 result = min(result, streams[j]->available());
1439 }
1440 return result;
1441 }
1442
1443 void resultAdd(float fact, int samples_eff) {
1444 // only accumulate samples that were actually read; tail is already zeroed
1445 for (int j = 0; j < samples_eff; j++) {
1446 result_vect[j] += static_cast<SumT>(current_vect[j] * fact);
1447 }
1448 }
1449
1450 void resultClear(int samples) {
1451 memset(result_vect.data(), 0, sizeof(SumT) * samples);
1452 }
1453};
1454
1464template <typename T>
1465class InputMerge : public AudioStream {
1466 public:
1468 InputMerge() = default;
1469
1473 InputMerge(Stream &left, Stream &right) {
1474 add(left, 1);
1475 add(right, 1);
1476 };
1477
1484
1485 virtual bool begin(AudioInfo info) {
1487 return begin();
1488 }
1489
1490 virtual bool begin() override {
1491 // make sure that we use the correct channel count
1493 return AudioStream::begin();
1494 }
1495
1497 size_t readBytes(uint8_t *data, size_t len) override {
1498 LOGD("readBytes: %d", (int)len);
1499 T *p_data = (T *)data;
1500 int result_len = min((size_t)available(), len);
1501 int frames = result_len / (sizeof(T) * total_channel_count);
1502 int result_idx = 0;
1503 for (int j = 0; j < frames; j++) {
1504 for (int i = 0; i < records.size(); i++) {
1505 for (int ch = 0; ch < records[i].channels; ch++) {
1506 p_data[result_idx++] =
1507 records[i].weight * readSample<T>(records[i].stream);
1508 }
1509 }
1510 }
1511 return result_idx * sizeof(T);
1512 }
1513
1515 void add(Stream &in, int channelCount, float weight = 1.0) {
1516 MergeRecord rec(&in, channelCount, weight);
1517 records.push_back(rec);
1519 }
1520
1523 void setWeight(int channel, float weight) {
1524 if (channel < channelCount()) {
1525 records[channel].weight = weight;
1526 } else {
1527 LOGE("Invalid channel %d - max is %d", channel, channelCount() - 1);
1528 }
1529 }
1530
1532 void end() override { records.clear(); }
1533
1536
1538 int available() override {
1539 int result = records[0].stream->available();
1540 for (int j = 1; j < channelCount(); j++) {
1541 int tmp = records[j].stream->available();
1542 if (tmp < result) {
1543 result = tmp;
1544 }
1545 }
1546 return result;
1547 }
1548
1549 protected:
1551 Stream *stream = nullptr;
1552 int channels = 0;
1553 float weight = 1.0;
1554 MergeRecord() = default;
1555 MergeRecord(Stream *str, int ch, float w) {
1556 stream = str;
1557 channels = ch;
1558 weight = w;
1559 }
1560 };
1563};
1564
1576 public:
1577 CallbackStream() = default;
1578
1581 CallbackStream(Stream &io, size_t (*cb_update)(uint8_t *data, size_t len)) {
1582 p_stream = &io;
1583 p_out = &io;
1585 }
1586
1588 CallbackStream(Print &out, size_t (*cb_update)(uint8_t *data, size_t len)) {
1589 p_out = &out;
1591 }
1592
1593 CallbackStream(size_t (*cb_read)(uint8_t *data, size_t len),
1594 size_t (*cb_write)(const uint8_t *data, size_t len)) {
1597 }
1598
1600 void setWriteCallback(size_t (*cb_write)(const uint8_t *data, size_t len)) {
1601 this->cb_write = cb_write;
1602 }
1603
1605 void setReadCallback(size_t (*cb_read)(uint8_t *data, size_t len)) {
1606 this->cb_read = cb_read;
1607 }
1608
1610 void setUpdateCallback(size_t (*cb_update)(uint8_t *data, size_t len)) {
1611 this->cb_update = cb_update;
1612 }
1613
1614 // callback result negative -> no change; callbeack result >=0 provides the
1615 // result
1616 void setAvailableCallback(int (*cb)()) { this->cb_available = cb; }
1617
1620 this->cb_audio_info = cb;
1621 }
1622
1624 void setAudioInfo(AudioInfo info) override {
1626 if (cb_audio_info != nullptr) {
1628 }
1629 }
1630
1631 virtual bool begin(AudioInfo info) {
1633 return begin();
1634 }
1635 virtual bool begin() override {
1636 active = true;
1637 return true;
1638 }
1639
1640 void end() override { active = false; }
1641
1642 int available() override {
1643 int result = AudioStream::available();
1644 // determine value from opional variable
1645 if (available_bytes >= 0) return available_bytes;
1646 // check if there is a callback
1647 if (cb_available == nullptr) return result;
1648 // determine value from callback
1650 if (tmp_available < 0) return result;
1651
1652 return tmp_available;
1653 }
1654
1655 size_t readBytes(uint8_t *data, size_t len) override {
1656 if (!active) return 0;
1657 // provide data from callback
1658 if (cb_read) {
1659 return cb_read(data, len);
1660 }
1661 // provide data from source
1662 size_t result = 0;
1663 if (p_stream) {
1664 result = p_stream->readBytes(data, len);
1665 }
1666 if (cb_update) {
1667 result = cb_update(data, result);
1668 }
1669 return result;
1670 }
1671
1672 size_t write(const uint8_t *data, size_t len) override {
1673 if (!active) return 0;
1674 // write to callback
1675 if (cb_write) {
1676 return cb_write(data, len);
1677 }
1678 // write to output
1679 if (p_out) {
1680 size_t result = len;
1681 if (cb_update) {
1682 result = cb_update((uint8_t *)data, len);
1683 }
1684 return p_out->write(data, result);
1685 }
1686 // no processing possible
1687 return 0;
1688 }
1689
1691 void setStream(Stream &in) override {
1692 p_stream = &in;
1693 p_out = &in;
1694 }
1695
1697 void setOutput(Print &out) override { p_out = &out; }
1698
1700 void setOutput(Stream &in) {
1701 p_stream = &in;
1702 p_out = &in;
1703 }
1704
1706 void setStream(Print &out) { p_out = &out; }
1707
1710
1711 protected:
1712 bool active = true;
1713 size_t (*cb_write)(const uint8_t *data, size_t len) = nullptr;
1714 size_t (*cb_read)(uint8_t *data, size_t len) = nullptr;
1715 size_t (*cb_update)(uint8_t *data, size_t len) = nullptr;
1717 int (*cb_available)() = nullptr;
1718 Stream *p_stream = nullptr;
1719 Print *p_out = nullptr;
1721};
1722
1730template <typename T = int16_t, class TF = float>
1732 public:
1733 FilteredStream() = default;
1736 this->channels = channels;
1737 setStream(stream);
1738 converter.setChannels(channels);
1739 }
1742 this->channels = channels;
1743 setOutput(stream);
1744 converter.setChannels(channels);
1745 }
1746
1747 virtual ~FilteredStream() { end(); }
1748
1749 void setStream(Stream &stream) override {
1750 p_stream = &stream;
1751 p_print = &stream;
1752 }
1753
1754 void setOutput(Print &stream) override { p_print = &stream; }
1755
1758 this->channels = info.channels;
1759 return begin();
1760 }
1761
1762 bool begin() override {
1763 if (channels == 0) {
1764 LOGE("channels must not be 0");
1765 return false;
1766 }
1767 converter.setChannels(channels);
1768 return AudioStream::begin();
1769 }
1770
1771 void end() override {
1773 }
1774
1775 virtual size_t write(const uint8_t *data, size_t len) override {
1776 if (p_print == nullptr) return 0;
1777 size_t result = converter.convert((uint8_t *)data, len);
1778 return p_print->write(data, result);
1779 }
1780
1781 size_t readBytes(uint8_t *data, size_t len) override {
1782 if (p_stream == nullptr) return 0;
1783 size_t result = p_stream->readBytes(data, len);
1784 result = converter.convert(data, result);
1785 return result;
1786 }
1787
1788 virtual int available() override {
1789 if (p_stream == nullptr) return 0;
1790 return p_stream->available();
1791 }
1792
1793 virtual int availableForWrite() override {
1794 if (p_print == nullptr) return 0;
1795 return p_print->availableForWrite();
1796 }
1797
1801 void setFilter(int channel, Filter<TF> *filter) {
1802 converter.setFilter(channel, filter);
1803 }
1804
1808 void setFilter(int channel, Filter<TF> &filter) {
1809 setFilter(channel, &filter);
1810 }
1811
1812 protected:
1813 int channels = 0;
1814 Stream *p_stream = nullptr;
1815 Print *p_print = nullptr;
1817};
1818
1820using ActivityCallback = void (*)(bool isActive);
1821
1832 public:
1833 VolumeMeter() = default;
1836 VolumeMeter(Print &print) { setOutput(print); }
1837 VolumeMeter(Stream &stream) { setStream(stream); }
1838
1841 return begin();
1842 }
1843
1844 bool begin() override {
1846 return true;
1847 }
1848
1849 void setAudioInfo(AudioInfo info) override {
1850 int channels = info.channels;
1851 LOGI("VolumeMeter::setAudioInfo: channels %d", channels);
1853 if (channels > 0) {
1854 volumes.resize(channels);
1855 volumes_tmp.resize(channels);
1856 sum.resize(channels);
1857 sum_tmp.resize(channels);
1858 }
1859 }
1860
1861 size_t write(const uint8_t *data, size_t len) override {
1862 updateVolumes(data, len);
1863 size_t result = len;
1864 if (p_out != nullptr) {
1865 result = p_out->write(data, len);
1866 }
1867 return result;
1868 }
1869
1870 size_t readBytes(uint8_t *data, size_t len) override {
1871 if (p_stream == nullptr) return 0;
1872 size_t result = p_stream->readBytes(data, len);
1873 updateVolumes((const uint8_t *)data, len);
1874 return result;
1875 }
1876
1879 float volume() { return f_volume; }
1880
1883 float volume(int channel) {
1884 if (volumes.size() == 0) {
1885 LOGE("begin not called!");
1886 return 0.0f;
1887 }
1888 if (channel >= volumes.size()) {
1889 LOGE("invalid channel %d", channel);
1890 return 0.0f;
1891 }
1892 return volumes[channel];
1893 }
1894
1899
1901 float volumeRatio(int channel) {
1903 }
1904
1906 float volumeDB() {
1907 // prevent infinite value
1908 if (volumeRatio() == 0) return -1000;
1909 return 20.0f * log10(volumeRatio());
1910 }
1911
1913 float volumeDB(int channel) {
1914 // prevent infinite value
1915 if (volumeRatio(channel) == 0) return -1000;
1916 return 20.0f * log10(volumeRatio(channel));
1917 }
1918
1920 float volumePercent() { return 100.0f * volumeRatio(); }
1921
1923 float volumePercent(int channel) { return 100.0f * volumeRatio(channel); }
1924
1926 float volumeAvg() {
1927 float total = 0;
1928 size_t count = 0;
1929 for (int j = 0; j < info.channels; j++) {
1930 total += sum[j];
1931 count += sample_count_per_channel;
1932 }
1933 return total / count;
1934 }
1935
1937 float volumeAvg(int channel) {
1938 return sum[channel] / sample_count_per_channel;
1939 }
1940
1942 void clear() {
1943 f_volume_tmp = 0;
1944 for (int j = 0; j < info.channels; j++) {
1945 volumes_tmp[j] = 0;
1946 sum_tmp[j] = 0;
1947 }
1948 }
1949
1954 void setActivityCallback(ActivityCallback callback, float threshold = 0.2, unsigned long duration_ms = 2000) {
1955 activity_callback = callback;
1956 activity_threshold = threshold;
1957 activity_duration_ms = duration_ms;
1958 activity_monitoring_enabled = (callback != nullptr);
1959 }
1960
1963 bool isActive() const {
1964 return is_active;
1965 }
1966
1969 setOutput((Print &)out);
1970 }
1973 setStream((Stream &)io);
1974 }
1975 void setOutput(Print &out) override { p_out = &out; }
1976 void setStream(Stream &io) override {
1977 p_out = &io;
1978 p_stream = &io;
1979 }
1980
1981 protected:
1982 float f_volume_tmp = 0;
1983 float f_volume = 0;
1988 Print *p_out = nullptr;
1989 Stream *p_stream = nullptr;
1991
1992 // Activity monitoring
1995 unsigned long activity_duration_ms = 0;
1997 bool is_active = false;
1998 unsigned long inactive_start_time = 0;
1999
2000 void updateVolumes(const uint8_t *data, size_t len) {
2001 if (data == nullptr || len == 0) return;
2002 clear();
2003 switch (info.bits_per_sample) {
2004 case 8:
2005 updateVolumesT<int8_t>(data, len);
2006 break;
2007 case 16:
2008 updateVolumesT<int16_t>(data, len);
2009 break;
2010 case 24:
2011 updateVolumesT<int24_t>(data, len);
2012 break;
2013 case 32:
2014 updateVolumesT<int32_t>(data, len);
2015 break;
2016 default:
2017 LOGE("Unsupported bits_per_sample: %d", info.bits_per_sample);
2018 break;
2019 }
2020 }
2021
2022 template <typename T>
2023 void updateVolumesT(const uint8_t *buffer, size_t size) {
2024 T *bufferT = (T *)buffer;
2025 int samplesCount = size / sizeof(T);
2027 for (int j = 0; j < samplesCount; j++) {
2028 float tmp = abs(static_cast<float>(bufferT[j]));
2029 updateVolume(tmp, j);
2030 }
2031 commit();
2032 }
2033
2034 void updateVolume(float tmp, int j) {
2035 if (tmp > f_volume_tmp) {
2036 f_volume_tmp = tmp;
2037 }
2038 if (volumes_tmp.size() > 0 && info.channels > 0) {
2039 int ch = j % info.channels;
2040 if (tmp > volumes_tmp[ch]) {
2041 volumes_tmp[ch] = tmp;
2042 sum_tmp[ch] = tmp;
2043 }
2044 }
2045 }
2046
2047 void commit() {
2049 for (int j = 0; j < info.channels; j++) {
2050 volumes[j] = volumes_tmp[j];
2051 sum[j] = sum_tmp[j];
2052 }
2054 }
2055
2057 if (!activity_monitoring_enabled || activity_callback == nullptr) return;
2058
2061 unsigned long current_time = millis();
2062
2063 if (above_threshold) {
2064 // Volume is above threshold - should be active
2065 if (!is_active) {
2066 is_active = true;
2067 activity_callback(true);
2068 }
2069 inactive_start_time = 0; // Reset inactive timer
2070 } else {
2071 // Volume is below threshold
2072 if (is_active) {
2073 // Currently active, check if we should transition to inactive
2074 if (inactive_start_time == 0) {
2075 // Start timing the inactive period
2076 inactive_start_time = current_time;
2077 } else if (current_time - inactive_start_time >= activity_duration_ms) {
2078 // Been below threshold long enough
2079 is_active = false;
2080 activity_callback(false);
2082 }
2083 }
2084 }
2085 }
2086};
2087
2088// legacy names
2092
2096
2110 public:
2160
2166
2174 return begin();
2175 }
2176
2181 bool begin() override {
2183 return true;
2184 }
2185
2194
2201 size_t write(const uint8_t *data, size_t len) override {
2202 size_t result = volume_meter.write(data, len);
2203 if (result > 0 && volume_meter.volumePercent() > limit_percent) {
2205 }
2206 return result;
2207 }
2208
2215 size_t readBytes(uint8_t *data, size_t len) override {
2216 size_t result = volume_meter.readBytes(data, len);
2217 if (result > 0 && volume_meter.volumePercent() > limit_percent) {
2219 }
2220 return result;
2221 }
2222
2227 void setOutput(Print &out) override { volume_meter.setOutput(out); }
2237 void setStream(Stream &io) override { volume_meter.setStream(io); }
2243
2249
2255 bool isActive(uint16_t time_ms = 1000) {
2256 return (millis() - time_over_last_volume_limit) < time_ms;
2257 }
2258
2259protected:
2263};
2264
2265#ifdef USE_TIMER
2280
2281// forward declaration: relevant only if use_timer == true
2282static void timerCallback(void *obj);
2293 friend void timerCallback(void *obj);
2294
2295 public:
2297
2299 TRACED();
2300 if (timer != nullptr) delete timer;
2301 if (buffer != nullptr) delete buffer;
2302 if (frame != nullptr) delete[] frame;
2303 }
2304
2310
2324
2328
2330 LOGD("%s: %s", LOG_METHOD,
2331 config.rx_tx_mode == RX_MODE ? "RX_MODE" : "TX_MODE");
2332 this->cfg = config;
2333 this->frameCallback = config.callback;
2334 if (cfg.use_timer) {
2336 frame = new uint8_t[frameSize];
2338 timer = new AudioTimer();
2340 if (cfg.timer_id >= 0) {
2342 }
2344 LOGI("sample_rate: %u -> time: %u milliseconds",
2345 (unsigned int)cfg.sample_rate, (unsigned int)time);
2348 }
2349
2351 active = true;
2352 }
2353
2355 bool begin() {
2356 TRACED();
2357 if (this->frameCallback != nullptr) {
2358 if (cfg.use_timer) {
2359 timer->begin(timerCallback, time, TimeUnit::US);
2360 }
2361 active = true;
2362 }
2363 return active;
2364 }
2365
2367 void end() {
2368 TRACED();
2369 if (cfg.use_timer) {
2370 timer->end();
2371 }
2372 active = false;
2373 }
2374
2377
2378 protected:
2380 bool active = false;
2382 // below only relevant with timer
2383 AudioTimer *timer = nullptr;
2385 uint8_t *frame = nullptr;
2388 unsigned long lastTimestamp = 0u;
2391
2392 // used for audio sink
2393 virtual size_t writeExt(const uint8_t *data, size_t len) override {
2394 if (!active) return 0;
2395 TRACED();
2396 size_t result = 0;
2397 if (!cfg.use_timer) {
2398 result = frameCallback((uint8_t *)data, len);
2399 } else {
2400 result = buffer->writeArray((uint8_t *)data, len);
2401 }
2402 if (++printCount % 10000 == 0) printSampleRate();
2403 return result;
2404 }
2405
2406 // used for audio source
2407 virtual size_t readExt(uint8_t *data, size_t len) override {
2408 if (!active) return 0;
2409 TRACED();
2410
2411 size_t result = 0;
2412 if (!cfg.use_timer) {
2413 result = frameCallback(data, len);
2414 } else {
2415 result = buffer->readArray(data, len);
2416 }
2417 if (++printCount % 10000 == 0) printSampleRate();
2418 return result;
2419 }
2420
2422 virtual void measureSampleRate() {
2423 unsigned long ms = millis();
2424 if (lastTimestamp > 0u) {
2426 if (diff > 0) {
2427 uint16_t rate = 1 * 1000 / diff;
2428
2429 if (currentRateValue == 0) {
2430 currentRateValue = rate;
2431 } else {
2432 currentRateValue = (currentRateValue + rate) / 2;
2433 }
2434 }
2435 }
2436 lastTimestamp = ms;
2437 }
2438
2440 virtual void printSampleRate() {
2441 LOGI("effective sample rate: %u", (unsigned int)currentRateValue);
2442 if (cfg.adapt_sample_rate &&
2443 abs((int)currentRateValue - (int)cfg.sample_rate) > 200) {
2446 }
2447 }
2448};
2449
2450// relevant only if use_timer == true
2453 if (src != nullptr) {
2454 // LOGD("%s: %s", LOG_METHOD, src->cfg.rx_tx_mode==RX_MODE ?
2455 // "RX_MODE":"TX_MODE");
2456 if (src->cfg.rx_tx_mode == RX_MODE) {
2457 // input
2458 uint16_t available_bytes = src->frameCallback(src->frame, src->frameSize);
2459 uint16_t buffer_available = src->buffer->availableForWrite();
2460 if (buffer_available < available_bytes) {
2461 // if buffer is full make space
2462 uint16_t to_clear = available_bytes - buffer_available;
2463 uint8_t tmp[to_clear];
2464 src->buffer->readArray(tmp, to_clear);
2465 }
2466 if (src->buffer->writeArray(src->frame, available_bytes) !=
2467 available_bytes) {
2468 assert(false);
2469 }
2470 } else {
2471 // output
2472 if (src->buffer != nullptr && src->frame != nullptr &&
2473 src->frameSize > 0) {
2474 uint16_t available_bytes =
2475 src->buffer->readArray(src->frame, src->frameSize);
2476 if (available_bytes !=
2477 src->frameCallback(src->frame, available_bytes)) {
2478 LOGE("data underflow");
2479 }
2480 }
2481 }
2482 src->measureSampleRate();
2483 }
2484}
2485
2486#endif
2487
2488} // namespace audio_tools
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define IRAM_ATTR
Definition AudioStreams.h:13
#define LOG_METHOD
Definition AudioToolsConfig.h:74
void loop()
#define DEFAULT_BUFFER_SIZE
Definition avr.h:20
#define assert(T)
Definition avr.h:10
Definition Arduino.h:56
virtual int availableForWrite()
Definition Arduino.h:128
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
virtual void flush()
Definition Arduino.h:130
Definition Arduino.h:136
virtual size_t readBytes(uint8_t *data, size_t len)
Definition Arduino.h:140
virtual int available()
Definition Arduino.h:139
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:174
virtual void addNotifyAudioChange(AudioInfoSupport &bi)
Adds target to be notified about audio changes.
Definition AudioTypes.h:149
Supports changes to the sampling rate, bits and channels.
Definition AudioTypes.h:131
virtual AudioInfo audioInfo()=0
provides the actual input AudioInfo
virtual void setAudioInfo(AudioInfo info)=0
Defines the input AudioInfo.
Monitors audio input and reports if the volume exceeds a specified limit within a given period.
Definition AudioStreams.h:2109
void setOutput(Print &out) override
Set the output target.
Definition AudioStreams.h:2227
void setStream(AudioStream &io)
Set the input stream.
Definition AudioStreams.h:2242
AudioInputMonitor(AudioOutput &ao, uint8_t limitPercent=20)
Construct a new AudioInputMonitor with an output.
Definition AudioStreams.h:2133
uint8_t limit_percent
Threshold percent.
Definition AudioStreams.h:2261
AudioInputMonitor(Print &print, uint8_t limitPercent=20)
Construct a new AudioInputMonitor with a Print output.
Definition AudioStreams.h:2142
bool isActive(uint16_t time_ms=1000)
Returns true if the volume exceeded the limit during the last period.
Definition AudioStreams.h:2255
VolumeMeter volume_meter
Volume calculation.
Definition AudioStreams.h:2260
AudioInputMonitor(uint8_t limitPercent=20)
Construct a new AudioInputMonitor with a volume limit in percent.
Definition AudioStreams.h:2115
void setOutput(AudioOutput &out)
Set the output target.
Definition AudioStreams.h:2232
size_t readBytes(uint8_t *data, size_t len) override
Read audio data from the monitor (same as VolumeMeter)
Definition AudioStreams.h:2215
uint64_t time_over_last_volume_limit
Last over-limit time (ms)
Definition AudioStreams.h:2262
VolumeMeter & getVolumeMeter()
Access the underlying VolumeMeter.
Definition AudioStreams.h:2248
size_t write(const uint8_t *data, size_t len) override
Write audio data to the monitor (same as VolumeMeter)
Definition AudioStreams.h:2201
uint8_t limitPercent() const
Get the current volume threshold as percent.
Definition AudioStreams.h:2165
AudioInputMonitor(Stream &stream, uint8_t limitPercent=20)
Construct a new AudioInputMonitor with a Stream input.
Definition AudioStreams.h:2151
bool begin() override
Begin processing with the current audio information.
Definition AudioStreams.h:2181
void setAudioInfo(AudioInfo info) override
Set the audio information.
Definition AudioStreams.h:2190
void setStream(Stream &io) override
Set the input stream.
Definition AudioStreams.h:2237
void setLimitPercent(uint8_t percent)
Set the volume threshold as percent.
Definition AudioStreams.h:2159
bool begin(AudioInfo info)
Begin processing with the given audio information.
Definition AudioStreams.h:2172
AudioInputMonitor(AudioStream &as, uint8_t limitPercent=20)
Construct a new AudioInputMonitor with an input stream.
Definition AudioStreams.h:2124
Abstract Audio Ouptut class.
Definition AudioOutput.h:25
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:120
AudioInfo info
Definition BaseStream.h:171
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition BaseStream.h:128
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition BaseStream.h:151
To be used to support implementations where the readBytes is not virtual.
Definition AudioStreams.h:23
AudioStreamWrapper(Stream &s)
Definition AudioStreams.h:25
virtual size_t readBytes(uint8_t *data, size_t len)
Definition AudioStreams.h:34
int32_t clientTimeout
Definition AudioStreams.h:58
int available()
Definition AudioStreams.h:44
virtual int availableForWrite()
Definition AudioStreams.h:52
virtual bool begin()
Definition AudioStreams.h:31
Stream * p_stream
Definition AudioStreams.h:57
virtual size_t write(const uint8_t *data, size_t len)
Definition AudioStreams.h:48
int peek()
Definition AudioStreams.h:42
int read()
Definition AudioStreams.h:40
virtual size_t write(uint8_t c)
Definition AudioStreams.h:46
virtual void flush()
Definition AudioStreams.h:54
virtual void end()
Definition AudioStreams.h:32
static uint32_t toTimeUs(uint32_t samplingRate, uint8_t limit=10)
converts sampling rate to delay in microseconds (μs)
Definition AudioTypes.h:238
Common Interface definition for AudioTimer.
Definition AudioTimer.h:30
virtual void setTimer(int timer)
Definition AudioTimer.h:61
virtual void setTimerFunction(TimerFunction function=DirectTimerCallback)
Definition AudioTimer.h:63
void setCallbackParameter(void *obj)
Definition AudioTimer.h:57
bool begin(repeating_timer_callback_t callback_f, uint32_t time, TimeUnit unit=MS)
Definition AudioTimer.h:44
bool end()
Definition AudioTimer.h:52
virtual int readArray(T data[], int len)
reads multiple values
Definition Buffers.h:34
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition Buffers.h:56
bool isEmpty()
Definition Buffers.h:87
Abstract Base class for Converters A converter is processing the data in the indicated array.
Definition BaseConverter.h:25
virtual size_t convert(uint8_t *src, size_t size)=0
virtual bool begin()
Definition BaseStream.h:40
virtual void end()
Definition BaseStream.h:41
virtual int available() override
Definition BaseStream.h:55
The Arduino Stream supports operations on single characters. This is usually not the best way to push...
Definition AudioStreams.h:569
void flush() override
empties the buffer
Definition AudioStreams.h:626
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioStreams.h:600
size_t minReadBufferSize
Definition AudioStreams.h:692
virtual size_t readExt(uint8_t *data, size_t len)
Definition AudioStreams.h:718
void setMinUnbufferedReadSize(size_t size)
Definition AudioStreams.h:686
size_t write(uint8_t c) override
writes a byte to the buffer
Definition AudioStreams.h:608
Stream * p_in
Definition AudioStreams.h:691
virtual size_t writeExt(const uint8_t *data, size_t len)
Definition AudioStreams.h:715
size_t readBytes(uint8_t *data, size_t len) override
Use this method !!
Definition AudioStreams.h:655
int peek() override
peeks a byte - to be avoided
Definition AudioStreams.h:645
void refill()
refills the buffer with data from the source
Definition AudioStreams.h:695
BufferedStream(Print &out, size_t buffer_size=1024)
Definition AudioStreams.h:576
int available() override
Returns the available bytes.
Definition AudioStreams.h:673
void setStream(Print &out)
Definition AudioStreams.h:601
size_t write(const uint8_t *data, size_t len) override
Use this method: write an array.
Definition AudioStreams.h:616
size_t peekBytes(uint8_t *data, size_t len)
Provides data w/o consuming.
Definition AudioStreams.h:665
Print * p_out
Definition AudioStreams.h:690
BufferedStream(size_t buffer_size)
Definition AudioStreams.h:571
SingleBuffer< uint8_t > buffer
Definition AudioStreams.h:689
void clear()
Clears all the data in the buffer.
Definition AudioStreams.h:679
int read() override
reads a byte - to be avoided
Definition AudioStreams.h:635
BufferedStream(Stream &io, size_t buffer_size=1024)
Definition AudioStreams.h:582
void refill(size_t len)
refill only if not enough data
Definition AudioStreams.h:710
void resize(int size)
Resize the buffer.
Definition AudioStreams.h:682
void setStream(Stream &io) override
Defines/Changes the input & output.
Definition AudioStreams.h:602
BufferedStream(size_t buffer_size, Print &out)
Definition AudioStreams.h:588
BufferedStream(size_t buffer_size, Stream &io)
Definition AudioStreams.h:594
CallbackStream: A Stream that allows to register callback methods for accessing and providing and upd...
Definition AudioStreams.h:1575
bool active
Definition AudioStreams.h:1712
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioStreams.h:1697
void setOutput(Stream &in)
same as setStream
Definition AudioStreams.h:1700
CallbackStream(Print &out, size_t(*cb_update)(uint8_t *data, size_t len))
Allows to change the audio before sending it to the output.
Definition AudioStreams.h:1588
size_t(* cb_read)(uint8_t *data, size_t len)
Definition AudioStreams.h:1714
virtual bool begin(AudioInfo info)
Definition AudioStreams.h:1631
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:1655
virtual bool begin() override
Definition AudioStreams.h:1635
void setReadCallback(size_t(*cb_read)(uint8_t *data, size_t len))
Instead of reading from the input stream we call this method.
Definition AudioStreams.h:1605
void end() override
Definition AudioStreams.h:1640
int available() override
Definition AudioStreams.h:1642
void setStream(Print &out)
same as set Output
Definition AudioStreams.h:1706
size_t(* cb_write)(const uint8_t *data, size_t len)
Definition AudioStreams.h:1713
size_t write(const uint8_t *data, size_t len) override
Definition AudioStreams.h:1672
CallbackStream(size_t(*cb_read)(uint8_t *data, size_t len), size_t(*cb_write)(const uint8_t *data, size_t len))
Definition AudioStreams.h:1593
void setAvailableCallback(int(*cb)())
Definition AudioStreams.h:1616
Stream * p_stream
Definition AudioStreams.h:1718
void(* cb_audio_info)(AudioInfo info)
Definition AudioStreams.h:1716
void setAvailable(int val)
optioinally define available bytes for next read
Definition AudioStreams.h:1709
Print * p_out
Definition AudioStreams.h:1719
int available_bytes
Definition AudioStreams.h:1720
int(* cb_available)()
Definition AudioStreams.h:1717
void setAudioInfo(AudioInfo info) override
Updates the audio info and calls the callback.
Definition AudioStreams.h:1624
void setStream(Stream &in) override
Defines/Changes the input & output.
Definition AudioStreams.h:1691
size_t(* cb_update)(uint8_t *data, size_t len)
Definition AudioStreams.h:1715
CallbackStream(Stream &io, size_t(*cb_update)(uint8_t *data, size_t len))
Definition AudioStreams.h:1581
void setWriteCallback(size_t(*cb_write)(const uint8_t *data, size_t len))
Instead of writing to the output stream we call this method.
Definition AudioStreams.h:1600
void setAudioInfoCallback(void(*cb)(AudioInfo info))
defines the callback to receive the actual audio info
Definition AudioStreams.h:1619
void setUpdateCallback(size_t(*cb_update)(uint8_t *data, size_t len))
After Reading or before writing we call this method to allow to modify the data.
Definition AudioStreams.h:1610
Converter for n Channels which applies the indicated Filter.
Definition BaseConverter.h:1691
Both the data of the read or write operations will be converted with the help of the indicated conver...
Definition AudioStreams.h:732
BaseConverter * p_converter
Definition AudioStreams.h:787
void setConverter(BaseConverter &cnv)
Definition AudioStreams.h:759
ConverterStream(Stream &stream, BaseConverter &converter)
Definition AudioStreams.h:738
ConverterStream(BaseConverter &converter)
Definition AudioStreams.h:736
virtual int availableForWrite()
Definition AudioStreams.h:761
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:772
void setStream(Stream &stream)
Defines/Changes the input & output.
Definition AudioStreams.h:748
Stream * p_stream
Definition AudioStreams.h:785
virtual size_t write(const uint8_t *data, size_t len)
Definition AudioStreams.h:763
Print * p_out
Definition AudioStreams.h:786
void setOutput(Print &out)
Defines/Changes the output target.
Definition AudioStreams.h:754
ConverterStream(Print &out, BaseConverter &converter)
Definition AudioStreams.h:743
virtual int available() override
Returns the available bytes in the buffer: to be avoided.
Definition AudioStreams.h:779
Abstract filter interface definition. Subclasses implement process() to transform audio samples one a...
Definition Filter.h:32
Stream to which we can apply Filters for each channel. The filter might change the result size!
Definition AudioStreams.h:1731
virtual size_t write(const uint8_t *data, size_t len) override
Definition AudioStreams.h:1775
void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioStreams.h:1749
int channels
Definition AudioStreams.h:1813
ConverterNChannels< T, TF > converter
Definition AudioStreams.h:1816
virtual ~FilteredStream()
Definition AudioStreams.h:1747
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:1781
void setOutput(Print &stream) override
Defines/Changes the output target.
Definition AudioStreams.h:1754
void setFilter(int channel, Filter< TF > &filter)
Definition AudioStreams.h:1808
void end() override
Definition AudioStreams.h:1771
virtual int availableForWrite() override
Definition AudioStreams.h:1793
FilteredStream(Stream &stream, int channels)
Definition AudioStreams.h:1735
Stream * p_stream
Definition AudioStreams.h:1814
FilteredStream(Stream &stream)
Definition AudioStreams.h:1734
void setFilter(int channel, Filter< TF > *filter)
Definition AudioStreams.h:1801
FilteredStream(Print &stream, int channels)
Definition AudioStreams.h:1741
bool begin() override
Definition AudioStreams.h:1762
FilteredStream(Print &stream)
Definition AudioStreams.h:1740
Print * p_print
Definition AudioStreams.h:1815
bool begin(AudioInfo info)
Definition AudioStreams.h:1756
virtual int available() override
Definition AudioStreams.h:1788
Source for reading generated tones. Please note.
Definition AudioStreams.h:454
bool active
Definition AudioStreams.h:554
void flush() override
Definition AudioStreams.h:548
void setInput(SoundGenerator< T > &generator)
Definition AudioStreams.h:463
const char * source_not_defined_error
Definition AudioStreams.h:558
void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition AudioStreams.h:475
void resize(int maxReadSize)
Redefine the buffer size which is reported in available()
Definition AudioStreams.h:551
size_t readBytes(uint8_t *data, size_t len) override
privide the data as byte stream
Definition AudioStreams.h:532
void end() override
stop the processing
Definition AudioStreams.h:512
AudioInfo defaultConfig()
Definition AudioStreams.h:467
GeneratedSoundStream(SoundGenerator< T > &generator)
Definition AudioStreams.h:458
bool isActive()
Definition AudioStreams.h:541
bool begin() override
start the processing
Definition AudioStreams.h:486
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioStreams.h:520
int buffer_size
Definition AudioStreams.h:556
bool begin(AudioInfo cfg)
start the processing
Definition AudioStreams.h:499
virtual int available() override
This is unbounded so we just return the buffer size.
Definition AudioStreams.h:529
SoundGenerator< T > * p_generator
Definition AudioStreams.h:555
Merges multiple input streams. So if you provide 2 mono channels you get a stereo signal as result wi...
Definition AudioStreams.h:1465
InputMerge()=default
Default constructor.
int total_channel_count
Definition AudioStreams.h:1562
virtual bool begin(AudioInfo info)
Definition AudioStreams.h:1485
size_t readBytes(uint8_t *data, size_t len) override
Provides the data from all streams mixed together.
Definition AudioStreams.h:1497
virtual bool begin() override
Definition AudioStreams.h:1490
Vector< MergeRecord > records
Definition AudioStreams.h:1561
void end() override
Remove all input streams.
Definition AudioStreams.h:1532
int available() override
Provides the min available data from all streams.
Definition AudioStreams.h:1538
void add(Stream &in, int channelCount, float weight=1.0)
Adds a new input stream with 1 channel.
Definition AudioStreams.h:1515
void setWeight(int channel, float weight)
Definition AudioStreams.h:1523
int channelCount()
Number of channels to which are mixed together = number of result channels.
Definition AudioStreams.h:1535
InputMerge(Stream &left, Stream &right)
Constructor for stereo signal from to mono input stream.
Definition AudioStreams.h:1473
AudioInfo audioInfo() override
Provides the audio info with the total channel count.
Definition AudioStreams.h:1479
MixerStream is mixing the input from Multiple Input Streams. All streams must have the same audo form...
Definition AudioStreams.h:1257
bool limit_available_data
Definition AudioStreams.h:1393
bool remove()
Removes all streams which have no data available.
Definition AudioStreams.h:1355
Vector< float > gains
Definition AudioStreams.h:1390
int nextEmptyIndex()
Provides you the index of the next empty stream. -1 when none is found.
Definition AudioStreams.h:1378
virtual bool begin(AudioInfo info)
Definition AudioStreams.h:1280
int indexOf(Stream &stream)
Provides the actual index of the stream.
Definition AudioStreams.h:1369
bool set(int index, Stream &in)
Replaces a stream at the indicated index.
Definition AudioStreams.h:1270
size_t readBytes(uint8_t *data, size_t len) override
Provides the data from all streams mixed together.
Definition AudioStreams.h:1313
void recalculateWeights()
Recalculate the weights.
Definition AudioStreams.h:1399
int add(Stream &in, int weight=100)
Adds a new input stream and returns it's actual index position.
Definition AudioStreams.h:1262
void resultAdd(float fact, int samples_eff)
Definition AudioStreams.h:1443
void end() override
Remove all input streams.
Definition AudioStreams.h:1300
bool remove(int idx)
Removes a stream by index position.
Definition AudioStreams.h:1344
Vector< int > weights
Definition AudioStreams.h:1389
int retry_count
Definition AudioStreams.h:1394
Vector< Stream * > streams
Definition AudioStreams.h:1388
int availableBytes()
Provides the available bytes from the first stream with data.
Definition AudioStreams.h:1435
void setLimitToAvailableData(bool flag)
Definition AudioStreams.h:1337
Vector< SumT > result_vect
Definition AudioStreams.h:1395
void setRetryCount(int retry)
Definition AudioStreams.h:1341
int total_weights
Definition AudioStreams.h:1391
Vector< T > current_vect
Definition AudioStreams.h:1396
int readBytesVector(T *p_data, int byteCount)
mixing using a vector of samples
Definition AudioStreams.h:1412
void resultClear(int samples)
Definition AudioStreams.h:1450
void setWeight(int index, int weight)
Definition AudioStreams.h:1290
int frame_size
Definition AudioStreams.h:1392
Stream * operator[](int idx)
Provides the stream pointer at the indicated index.
Definition AudioStreams.h:1372
int size()
Number of stremams to which are mixed together.
Definition AudioStreams.h:1310
Class which measures the thruput.
Definition AudioStreams.h:796
virtual size_t write(const uint8_t *data, size_t len) override
Writes raw PCM audio data, which will be the input for the volume control.
Definition AudioStreams.h:844
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioStreams.h:833
uint32_t estimatedTotalTimeFor(uint32_t totalBytes)
Provides the estimated runtime in milliseconds for the indicated total.
Definition AudioStreams.h:898
bool report_bytes
Definition AudioStreams.h:933
uint32_t ms_at_begin
Definition AudioStreams.h:935
uint32_t start_time
Definition AudioStreams.h:927
uint32_t timeSinceBegin()
Provides the time in ms since the last call of begin()
Definition AudioStreams.h:892
size_t readBytes(uint8_t *data, size_t len) override
Provides the data from all streams mixed together.
Definition AudioStreams.h:836
MeasuringStream(Stream &stream, int count=10, Print *logOut=nullptr)
Definition AudioStreams.h:815
int framesPerSecond()
Returns the actual thrughput in frames (samples) per second.
Definition AudioStreams.h:858
uint32_t bytesSinceBegin()
Provides the total processed bytes since the last call of begin()
Definition AudioStreams.h:895
int available() override
Definition AudioStreams.h:841
virtual int availableForWrite() override
Provides the nubmer of bytes we can write.
Definition AudioStreams.h:850
MeasuringStream(int count=10, Print *logOut=nullptr)
Definition AudioStreams.h:798
uint32_t total_bytes_since_begin
Definition AudioStreams.h:936
Stream * p_stream
Definition AudioStreams.h:925
size_t measure(size_t len)
Definition AudioStreams.h:938
int total_bytes
Definition AudioStreams.h:928
void setFrameSize(int size)
Trigger reporting in frames (=samples) per second.
Definition AudioStreams.h:884
int max_count
Definition AudioStreams.h:923
void setReportBytes(bool flag)
Report in bytes instead of samples.
Definition AudioStreams.h:887
uint32_t estimatedOpenTimeFor(uint32_t totalBytes)
Provides the estimated time from now to the end in ms.
Definition AudioStreams.h:905
const char * name
Definition AudioStreams.h:934
void setLogOutput(Print &out)
Defines the logging output.
Definition AudioStreams.h:824
int bytes_per_second
Definition AudioStreams.h:929
MeasuringStream(Print &print, int count=10, Print *logOut=nullptr)
Definition AudioStreams.h:807
bool setProcessedBytes(uint32_t pos)
Definition AudioStreams.h:912
Print * p_logout
Definition AudioStreams.h:932
void printResult()
Definition AudioStreams.h:956
void setName(const char *name)
Definition AudioStreams.h:889
uint32_t startTime()
Provides the time when the last measurement was started.
Definition AudioStreams.h:864
bool begin() override
Definition AudioStreams.h:872
Print * p_print
Definition AudioStreams.h:926
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition AudioStreams.h:866
int count
Definition AudioStreams.h:924
int frame_size
Definition AudioStreams.h:930
void setStream(Stream &io) override
Defines/Changes the input & output.
Definition AudioStreams.h:827
bool begin(AudioInfo info)
Definition AudioStreams.h:878
NullStream null
Definition AudioStreams.h:931
int bytesPerSecond()
Returns the actual thrughput in bytes per second.
Definition AudioStreams.h:855
A simple Stream implementation which is backed by allocated memory.
Definition AudioStreams.h:95
virtual size_t write(const uint8_t *data, size_t len) override
Definition AudioStreams.h:181
MemoryStream(const uint8_t *buffer, int buffer_size, bool isActive=true, MemoryType memoryType=FLASH_RAM)
Definition AudioStreams.h:110
virtual void setLoop(bool loop, int rewindPos)
Automatically rewinds to the indicated position when reaching the end.
Definition AudioStreams.h:281
virtual void clear(bool reset=false)
clears the audio data: sets all values to 0
Definition AudioStreams.h:251
virtual uint8_t * data()
Provides access to the data array.
Definition AudioStreams.h:309
virtual int read() override
Definition AudioStreams.h:214
~MemoryStream()
Definition AudioStreams.h:129
bool is_active
Definition AudioStreams.h:343
void setValue(const uint8_t *buffer, int buffer_size, MemoryType memoryType=FLASH_RAM)
Update the values (buffer and size)
Definition AudioStreams.h:325
MemoryStream(MemoryStream &&source)
Move Constructor.
Definition AudioStreams.h:123
uint8_t * buffer
Definition AudioStreams.h:339
virtual size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:222
MemoryStream(MemoryStream &source)
Copy Constructor.
Definition AudioStreams.h:120
virtual int availableForWrite() override
Definition AudioStreams.h:208
void(* rewind_cb)()
Definition AudioStreams.h:342
virtual size_t write(uint8_t byte) override
Definition AudioStreams.h:168
virtual void setLoop(bool loop)
Definition AudioStreams.h:270
virtual bool resize(size_t size)
Definition AudioStreams.h:288
virtual bool setAvailable(size_t len)
update the write_pos (e.g. when we used data() to update the array)
Definition AudioStreams.h:312
int write_pos
Definition AudioStreams.h:335
MemoryType memory_type
Definition AudioStreams.h:340
int read_pos
Definition AudioStreams.h:336
virtual int peek() override
Definition AudioStreams.h:234
bool owns_memory
Definition AudioStreams.h:344
bool memoryCanChange()
Definition AudioStreams.h:346
MemoryStream(int buffer_size, MemoryType memoryType)
Constructor for alloction in RAM.
Definition AudioStreams.h:100
int rewind_pos
Definition AudioStreams.h:338
void rewind()
Resets the read pointer.
Definition AudioStreams.h:162
bool begin() override
resets the read pointer and write pointer if the memory is changeable
Definition AudioStreams.h:150
void copy(MemoryStream &source)
Definition AudioStreams.h:348
virtual void end() override
Definition AudioStreams.h:245
MemoryStream & operator=(MemoryStream &other)
copy assignement operator
Definition AudioStreams.h:135
bool begin(AudioInfo info)
Define some audio info and start the processing.
Definition AudioStreams.h:144
int buffer_size
Definition AudioStreams.h:337
void setRewindCallback(void(*cb)())
Callback which is executed when we rewind (in loop mode) to the beginning.
Definition AudioStreams.h:322
virtual void flush() override
Definition AudioStreams.h:243
bool is_loop
Definition AudioStreams.h:341
virtual int available() override
Definition AudioStreams.h:194
Abstract class: Objects can be put into a pipleline.
Definition AudioStreams.h:68
virtual void setStream(Stream &in)=0
Defines/Changes the input & output.
virtual void setOutput(AudioOutput &out)
Defines/Changes the output target and registers for audio change notifications.
Definition AudioStreams.h:82
virtual void setOutput(Print &out)=0
Defines/Changes the output target.
virtual void setStream(AudioStream &io)
Defines/Changes the input & output and registers for audio change notifications.
Definition AudioStreams.h:76
The Arduino Stream which provides silence and simulates a null device when used as audio target or au...
Definition BaseStream.h:340
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition AudioTypes.h:297
Generic calss to measure the the total bytes which were processed in order to calculate the progress ...
Definition AudioStreams.h:989
bool begin(size_t len)
Definition AudioStreams.h:1027
ProgressStream(Print &print)
Definition AudioStreams.h:993
virtual size_t write(const uint8_t *data, size_t len) override
Writes raw PCM audio data, which will be the input for the volume control.
Definition AudioStreams.h:1077
bool begin(ProgressStreamInfo info)
Definition AudioStreams.h:1032
size_t size()
Provides the current total size (defined by setSize)
Definition AudioStreams.h:1045
void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioStreams.h:1009
ProgressStreamInfo & defaultConfig()
Definition AudioStreams.h:1002
size_t total_processed
Definition AudioStreams.h:1093
size_t totalSecs()
Converts the totalBytes() to seconds.
Definition AudioStreams.h:1057
ProgressStreamInfo progress_info
Definition AudioStreams.h:1089
size_t byteRate()
Definition AudioStreams.h:1100
size_t readBytes(uint8_t *data, size_t len) override
Provides the data from all streams mixed together.
Definition AudioStreams.h:1066
size_t processedBytes()
Provides the number of processed bytes.
Definition AudioStreams.h:1048
void setPrint(Print &print)
Definition AudioStreams.h:1016
int available() override
Definition AudioStreams.h:1071
void setSize(size_t len)
Updates the total size and restarts the percent calculation.
Definition AudioStreams.h:1039
virtual int availableForWrite() override
Provides the nubmer of bytes we can write.
Definition AudioStreams.h:1083
Stream * p_stream
Definition AudioStreams.h:1090
size_t measure(size_t len)
Definition AudioStreams.h:1095
float percentage()
Provides the processed percentage: If no size has been defined we return 0.
Definition AudioStreams.h:1060
AudioInfoSupport * p_info_from
Definition AudioStreams.h:1092
size_t processedSecs()
Provides the number of processed seconds.
Definition AudioStreams.h:1051
bool begin() override
Definition AudioStreams.h:1018
Print * p_print
Definition AudioStreams.h:1091
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition AudioStreams.h:1004
size_t totalBytes()
Provides the total_size provided in the configuration.
Definition AudioStreams.h:1054
void setStream(Print &print)
Definition AudioStreams.h:1014
ProgressStream(Stream &stream)
Definition AudioStreams.h:995
ProgressStream(AudioStream &stream)
Definition AudioStreams.h:997
Configuration for ProgressStream.
Definition AudioStreams.h:978
size_t total_size
Definition AudioStreams.h:980
Implements a typed Ringbuffer.
Definition Buffers.h:353
bool peek(T &result) override
peeks the actual entry from the buffer
Definition Buffers.h:373
bool read(T &result) override
reads a single value
Definition Buffers.h:360
virtual int availableForWrite() override
provides the number of entries that are available to write
Definition Buffers.h:425
virtual bool write(T data) override
write add an entry to the buffer
Definition Buffers.h:403
virtual size_t size() override
Returns the maximum capacity of the buffer.
Definition Buffers.h:440
virtual bool resize(size_t len)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:430
virtual int available() override
provides the number of entries that are available to read
Definition Buffers.h:422
An AudioStream backed by a Ringbuffer. We can write to the end and read from the beginning of the str...
Definition AudioStreams.h:398
virtual size_t write(const uint8_t *data, size_t len) override
Definition AudioStreams.h:427
size_t size()
Definition AudioStreams.h:436
virtual int read() override
Definition AudioStreams.h:417
RingBufferStream(int size=DEFAULT_BUFFER_SIZE)
Definition AudioStreams.h:400
virtual size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:423
virtual int availableForWrite() override
Definition AudioStreams.h:407
virtual int peek() override
Definition AudioStreams.h:412
virtual size_t write(uint8_t c) override
Definition AudioStreams.h:432
void resize(int size)
Definition AudioStreams.h:434
RingBuffer< uint8_t > buffer
Definition AudioStreams.h:439
virtual void flush() override
Definition AudioStreams.h:411
virtual int available() override
Definition AudioStreams.h:402
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition Buffers.h:184
size_t setAvailable(size_t available_size)
Definition Buffers.h:308
void trim()
Moves the unprocessed data to the beginning of the buffer.
Definition Buffers.h:285
bool write(T sample) override
write add an entry to the buffer
Definition Buffers.h:218
bool peek(T &result) override
peeks the actual entry from the buffer
Definition Buffers.h:236
bool read(T &result) override
reads a single value
Definition Buffers.h:227
int available() override
provides the number of entries that are available to read
Definition Buffers.h:245
int availableForWrite() override
provides the number of entries that are available to write
Definition Buffers.h:250
T * address() override
Provides address to beginning of the buffer.
Definition Buffers.h:293
bool isFull() override
checks if the buffer is full
Definition Buffers.h:252
int peekArray(uint8_t *data, int len)
Definition Buffers.h:254
bool resize(size_t size)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:317
void reset() override
clears the buffer
Definition Buffers.h:298
Base class to define the abstract interface for the sound generating classes.
Definition SoundGenerator.h:28
virtual size_t readBytes(uint8_t *data, size_t len)
Provides the data as byte array with the requested number of channels.
Definition SoundGenerator.h:63
virtual bool begin(AudioInfo info)
Starts the processing with the provided AudioInfo.
Definition SoundGenerator.h:35
virtual bool isActive()
Checks if the begin method has been called - after end() isActive is false.
Definition SoundGenerator.h:57
virtual void setAudioInfo(AudioInfo info)
Defines/updates the AudioInfo.
Definition SoundGenerator.h:91
virtual AudioInfo audioInfo()
Provides the AudioInfo.
Definition SoundGenerator.h:88
virtual void end()
Ends the processing.
Definition SoundGenerator.h:54
virtual AudioInfo defaultConfig()
Provides the default configuration.
Definition SoundGenerator.h:76
Throttle the sending or receiving of the audio data to limit it to the indicated sample rate.
Definition AudioStreams.h:1131
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioStreams.h:1144
uint32_t sum_frames
Definition AudioStreams.h:1240
Throttle(Print &out)
Definition AudioStreams.h:1134
Stream * p_in
Definition AudioStreams.h:1244
Throttle(Stream &io)
Definition AudioStreams.h:1135
uint32_t start_time
Definition AudioStreams.h:1239
ThrottleConfig cfg
Definition AudioStreams.h:1241
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:1197
int64_t getDelayMs(uint64_t frames)
Definition AudioStreams.h:1230
int available() override
Definition AudioStreams.h:1192
size_t write(const uint8_t *data, size_t len) override
Definition AudioStreams.h:1186
int availableForWrite() override
Definition AudioStreams.h:1179
void delayFrames(size_t frames)
Definition AudioStreams.h:1211
void delayBytes(size_t bytes)
Definition AudioStreams.h:1208
bool begin(ThrottleConfig cfg)
Definition AudioStreams.h:1151
Print * p_out
Definition AudioStreams.h:1243
int64_t getDelayUs(uint64_t frames)
Definition AudioStreams.h:1226
int64_t getDelaySec(uint64_t frames)
Definition AudioStreams.h:1234
void startDelay()
Definition AudioStreams.h:1174
bool begin() override
Definition AudioStreams.h:1167
int frame_size
Definition AudioStreams.h:1242
void setStream(Stream &io) override
Defines/Changes the input & output.
Definition AudioStreams.h:1138
ThrottleConfig defaultConfig()
Definition AudioStreams.h:1146
bool begin(AudioInfo info)
Definition AudioStreams.h:1159
Callback driven Audio Source (rx_tx_mode==RX_MODE) or Audio Sink (rx_tx_mode==TX_MODE)....
Definition AudioStreams.h:2292
bool active
Definition AudioStreams.h:2380
void begin(TimerCallbackAudioStreamInfo config)
Definition AudioStreams.h:2329
TimerCallbackAudioStream()
Definition AudioStreams.h:2296
TimerCallbackAudioStreamInfo audioInfoExt()
Provides the current audio information.
Definition AudioStreams.h:2326
uint16_t currentSampleRate()
Provides the effective sample rate.
Definition AudioStreams.h:2376
virtual size_t writeExt(const uint8_t *data, size_t len) override
Definition AudioStreams.h:2393
AudioTimer * timer
Definition AudioStreams.h:2383
uint16_t frameSize
Definition AudioStreams.h:2386
TimerCallbackAudioStreamInfo defaultConfig()
Provides the default configuration.
Definition AudioStreams.h:2306
bool begin()
Restart the processing.
Definition AudioStreams.h:2355
uint32_t currentRateValue
Definition AudioStreams.h:2389
friend void timerCallback(void *obj)
Definition AudioStreams.h:2451
AudioInfo audioInfo()
provides the actual input AudioInfo
Definition AudioStreams.h:2327
virtual void measureSampleRate()
calculates the effective sample rate
Definition AudioStreams.h:2422
virtual void setAudioInfo(AudioInfo info)
updates the audio information
Definition AudioStreams.h:2312
virtual void printSampleRate()
log and update effective sample rate
Definition AudioStreams.h:2440
virtual size_t readExt(uint8_t *data, size_t len) override
Definition AudioStreams.h:2407
RingBuffer< uint8_t > * buffer
Definition AudioStreams.h:2384
~TimerCallbackAudioStream()
Definition AudioStreams.h:2298
void end()
Stops the processing.
Definition AudioStreams.h:2367
unsigned long lastTimestamp
Definition AudioStreams.h:2388
TimerCallbackAudioStreamInfo cfg
Definition AudioStreams.h:2379
uint32_t time
Definition AudioStreams.h:2387
uint32_t printCount
Definition AudioStreams.h:2390
uint8_t * frame
Definition AudioStreams.h:2385
uint16_t(* frameCallback)(uint8_t *data, uint16_t len)
Definition AudioStreams.h:2381
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
void erase(iterator it)
Definition Vector.h:294
int indexOf(T obj)
Definition Vector.h:320
void push_back(T &&value)
Definition Vector.h:182
void clear()
Definition Vector.h:176
bool resize(size_t newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
int size()
Definition Vector.h:178
A simple class to determine the volume. You can use it as final output or as output or input in your ...
Definition AudioStreams.h:1831
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioStreams.h:1975
void setStream(AudioStream &io)
Defines/Changes the input & output and registers for audio change notifications.
Definition AudioStreams.h:1971
float volumeRatio()
Volume Ratio: max amplitude is 1.0.
Definition AudioStreams.h:1896
float volumeAvg(int channel)
Average volume of indicated channel.
Definition AudioStreams.h:1937
float volume()
Definition AudioStreams.h:1879
Vector< float > sum
Definition AudioStreams.h:1986
size_t sample_count_per_channel
Definition AudioStreams.h:1990
Vector< float > volumes_tmp
Definition AudioStreams.h:1985
VolumeMeter(AudioOutput &ao)
Definition AudioStreams.h:1835
bool isActive() const
Definition AudioStreams.h:1963
bool is_active
Definition AudioStreams.h:1997
unsigned long activity_duration_ms
Definition AudioStreams.h:1995
float volumePercent()
Volume in %: max amplitude is 100.
Definition AudioStreams.h:1920
void updateVolumes(const uint8_t *data, size_t len)
Definition AudioStreams.h:2000
void setOutput(AudioOutput &out)
Defines/Changes the output target and registers for audio change notifications.
Definition AudioStreams.h:1967
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:1870
Vector< float > volumes
Definition AudioStreams.h:1984
float f_volume_tmp
Definition AudioStreams.h:1982
size_t write(const uint8_t *data, size_t len) override
Definition AudioStreams.h:1861
Stream * p_stream
Definition AudioStreams.h:1989
unsigned long inactive_start_time
Definition AudioStreams.h:1998
float volumePercent(int channel)
Volume of indicated channel in %: max amplitude is 100.
Definition AudioStreams.h:1923
float volumeAvg()
Average volume of all channels.
Definition AudioStreams.h:1926
float f_volume
Definition AudioStreams.h:1983
void updateVolumesT(const uint8_t *buffer, size_t size)
Definition AudioStreams.h:2023
bool activity_monitoring_enabled
Definition AudioStreams.h:1996
Print * p_out
Definition AudioStreams.h:1988
Vector< float > sum_tmp
Definition AudioStreams.h:1987
VolumeMeter(Stream &stream)
Definition AudioStreams.h:1837
void updateVolume(float tmp, int j)
Definition AudioStreams.h:2034
void setActivityCallback(ActivityCallback callback, float threshold=0.2, unsigned long duration_ms=2000)
Definition AudioStreams.h:1954
void updateActivityState()
Definition AudioStreams.h:2056
void clear()
Resets the actual volume.
Definition AudioStreams.h:1942
bool begin() override
Definition AudioStreams.h:1844
float volumeRatio(int channel)
Volume Ratio of indicated channel: max amplitude is 1.0.
Definition AudioStreams.h:1901
float activity_threshold
Definition AudioStreams.h:1994
float volumeDB(int channel)
Volume of indicated channel in db: max amplitude is 0.
Definition AudioStreams.h:1913
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition AudioStreams.h:1849
void commit()
Definition AudioStreams.h:2047
ActivityCallback activity_callback
Definition AudioStreams.h:1993
void setStream(Stream &io) override
Defines/Changes the input & output.
Definition AudioStreams.h:1976
float volumeDB()
Volume in db: max amplitude is 0 (range: -1000 to 0)
Definition AudioStreams.h:1906
VolumeMeter(Print &print)
Definition AudioStreams.h:1836
bool begin(AudioInfo info)
Definition AudioStreams.h:1839
float volume(int channel)
Definition AudioStreams.h:1883
VolumeMeter(AudioStream &as)
Definition AudioStreams.h:1834
#define URL_CLIENT_TIMEOUT
Definition esp8266.h:23
MemoryType
Memory types.
Definition AudioTypes.h:33
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:26
@ RAM
Definition AudioTypes.h:33
@ PS_RAM
Definition AudioTypes.h:33
@ FLASH_RAM
Definition AudioTypes.h:33
@ RX_MODE
Definition AudioTypes.h:26
@ US
Definition AudioTypes.h:44
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
TimerFunction
Definition AudioTimerBase.h:16
@ DirectTimerCallback
Definition AudioTimerBase.h:17
size_t readSamples(Stream *p_stream, T *data, int samples, int retryCount=-1)
guaranteed to return the requested data
Definition AudioTypes.h:466
static void timerCallback(void *obj)
Definition AudioStreams.h:2451
void delay(uint32_t ms)
Definition Arduino.h:255
uint64_t micros()
Definition Arduino.h:261
void(*)(bool isActive) ActivityCallback
Callback function type for activity state changes.
Definition AudioStreams.h:1820
void delayMicroseconds(uint32_t us)
Definition Arduino.h:257
uint32_t millis()
Returns the milliseconds since the start.
Definition Arduino.h:256
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
void copyFrom(AudioInfo info)
Same as set.
Definition AudioTypes.h:101
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
virtual void clear()
Definition AudioTypes.h:115
Definition AudioStreams.h:1550
int channels
Definition AudioStreams.h:1552
MergeRecord(Stream *str, int ch, float w)
Definition AudioStreams.h:1555
float weight
Definition AudioStreams.h:1553
Stream * stream
Definition AudioStreams.h:1551
Configure Throttle setting.
Definition AudioStreams.h:1116
ThrottleConfig()
Definition AudioStreams.h:1117
int correction_us
Definition AudioStreams.h:1122
TimerCallbackAudioStream Configuration.
Definition AudioStreams.h:2271
TimerFunction timer_function
Definition AudioStreams.h:2276
RxTxMode rx_tx_mode
Definition AudioStreams.h:2272
uint16_t(* callback)(uint8_t *data, uint16_t len)
Definition AudioStreams.h:2278
bool use_timer
Definition AudioStreams.h:2274
int timer_id
Definition AudioStreams.h:2275
bool adapt_sample_rate
Definition AudioStreams.h:2277
uint16_t buffer_size
Definition AudioStreams.h:2273