arduino-audio-tools
Loading...
Searching...
No Matches
AudioStreams.h
Go to the documentation of this file.
1#pragma once
10#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 }
480 }
481
483 bool begin() override {
484 TRACED();
485 if (p_generator == nullptr) {
487 return false;
488 }
491 active = true;
492 return active;
493 }
494
496 bool begin(AudioInfo cfg) {
497 TRACED();
498 if (p_generator == nullptr) {
500 return false;
501 }
502 p_generator->begin(cfg);
504 active = true;
505 return active;
506 }
507
509 void end() override {
510 TRACED();
511 if (p_generator != nullptr) {
512 p_generator->end();
513 }
514 active = true; // legacy support - most sketches do not call begin
515 }
516
517 AudioInfo audioInfo() override {
518 if (p_generator == nullptr) {
520 return AudioStream::audioInfo();
521 }
522 return p_generator->audioInfo();
523 }
524
526 virtual int available() override { return active ? buffer_size : 0; }
527
529 size_t readBytes(uint8_t *data, size_t len) override {
530 if (!active) return 0;
531 if (p_generator == nullptr) {
532 return 0;
533 }
534 LOGD("GeneratedSoundStream::readBytes: %u", (unsigned int)len);
535 return p_generator->readBytes(data, len);
536 }
537
538 bool isActive() {
539 if (p_generator == nullptr) return false;
540 return active && p_generator->isActive();
541 }
542
543 operator bool() override { return isActive(); }
544
545 void flush() override {}
546
549
550 protected:
551 bool active = true; // support for legacy sketches
554 DEFAULT_BUFFER_SIZE * 100; // there is no reason to limit this
555 const char *source_not_defined_error = "Source not defined";
556};
557
567 public:
568 BufferedStream(size_t buffer_size) {
569 TRACED();
570 if (buffer_size > 0) resize(buffer_size);
571 }
572
573 BufferedStream(Print &out, size_t buffer_size = 1024) {
574 TRACED();
575 setOutput(out);
576 if (buffer_size > 0) resize(buffer_size);
577 }
578
579 BufferedStream(Stream &io, size_t buffer_size = 1024) {
580 TRACED();
581 setStream(io);
582 if (buffer_size > 0) resize(buffer_size);
583 }
584
585 BufferedStream(size_t buffer_size, Print &out) {
586 TRACED();
587 setOutput(out);
588 if (buffer_size > 0) resize(buffer_size);
589 }
590
591 BufferedStream(size_t buffer_size, Stream &io) {
592 TRACED();
593 setStream(io);
594 if (buffer_size > 0) resize(buffer_size);
595 }
596
597 void setOutput(Print &out) override { p_out = &out; }
598 void setStream(Print &out) { setOutput(out); }
599 void setStream(Stream &io) override {
600 p_in = &io;
601 p_out = &io;
602 }
603
605 size_t write(uint8_t c) override {
606 if (buffer.isFull()) {
607 flush();
608 }
609 return buffer.write(c);
610 }
611
613 size_t write(const uint8_t *data, size_t len) override {
614 LOGD("%s: %zu", LOG_METHOD, len);
615 int result = 0;
616 for (int j = 0; j < len; j++) {
617 result += write(data[j]);
618 }
619 return result;
620 }
621
623 void flush() override {
624 // just dump the memory of the buffer and clear it
625 if (buffer.available() > 0) {
627 buffer.reset();
628 }
629 }
630
632 int read() override {
633 if (buffer.isEmpty()) {
634 refill();
635 }
636 uint8_t result = 0;
637 if (!buffer.read(result)) return -1;
638 return result;
639 }
640
642 int peek() override {
643 if (buffer.isEmpty()) {
644 refill();
645 }
646 uint8_t result = 0;
647 if (!buffer.peek(result)) return -1;
648 return result;
649 };
650
652 size_t readBytes(uint8_t *data, size_t len) override {
653 if (buffer.isEmpty() && len >= minReadBufferSize) {
654 return readExt(data, len);
655 } else {
656 refill(len);
657 return buffer.readArray(data, len);
658 }
659 }
660
662 size_t peekBytes(uint8_t *data, size_t len) {
663 if (buffer.isEmpty()) {
664 refill();
665 }
666 return buffer.peekArray(data, len);
667 }
668
670 int available() override {
671 if (p_in == nullptr) return 0;
672 return buffer.available() + p_in->available();
673 }
674
676 void clear() { buffer.reset(); }
677
679 void resize(int size) { buffer.resize(size); }
680
683 void setMinUnbufferedReadSize(size_t size) { minReadBufferSize = size; }
684
685 protected:
687 Print *p_out = nullptr;
688 Stream *p_in = nullptr;
689 size_t minReadBufferSize = 1024;
690
692 void refill() {
693 // Preserve any existing unread data then append new bytes
694 buffer.trim();
697 if (free_space == 0) {
698 // Buffer full – nothing we can append
699 return;
700 }
701 // Read new data directly behind existing bytes
704 }
705
707 void refill(size_t len) {
708 if (buffer.available() >= len) return;
709 refill();
710 }
711
712 virtual size_t writeExt(const uint8_t *data, size_t len) {
713 return p_out == nullptr ? 0 : p_out->write(data, len);
714 }
715 virtual size_t readExt(uint8_t *data, size_t len) {
716 return p_in == nullptr ? 0 : p_in->readBytes(data, len);
717 }
718};
719
728template <typename T = int16_t>
730 public:
731 ConverterStream() = default;
732
733 ConverterStream(BaseConverter &converter) { setConverter(converter); }
734
735 ConverterStream(Stream &stream, BaseConverter &converter) {
736 setConverter(converter);
737 setStream(stream);
738 }
739
741 setConverter(converter);
742 setOutput(out);
743 }
744
745 void setStream(Stream &stream) {
746 TRACEI();
747 p_stream = &stream;
748 p_out = &stream;
749 }
750
751 void setOutput(Print &out) {
752 TRACEI();
753 p_out = &out;
754 }
755
757
758 virtual int availableForWrite() { return p_out->availableForWrite(); }
759
760 virtual size_t write(const uint8_t *data, size_t len) {
761 size_t result = p_converter->convert((uint8_t *)data, len);
762 if (result > 0) {
763 size_t result_written = p_out->write(data, result);
764 return len * result_written / result;
765 }
766 return 0;
767 }
768
769 size_t readBytes(uint8_t *data, size_t len) override {
770 if (p_stream == nullptr) return 0;
771 size_t result = p_stream->readBytes(data, len);
772 return p_converter->convert(data, result);
773 }
774
776 virtual int available() override {
777 if (p_stream == nullptr) return 0;
778 return p_stream->available();
779 }
780
781 protected:
782 Stream *p_stream = nullptr;
783 Print *p_out = nullptr;
785};
786
794 public:
795 MeasuringStream(int count = 10, Print *logOut = nullptr) {
796 this->count = count;
797 this->max_count = count;
798 p_stream = &null;
799 p_print = &null;
800 start_time = millis();
802 }
803
804 MeasuringStream(Print &print, int count = 10, Print *logOut = nullptr) {
805 this->count = count;
806 this->max_count = count;
807 setOutput(print);
808 start_time = millis();
810 }
811
812 MeasuringStream(Stream &stream, int count = 10, Print *logOut = nullptr) {
813 this->count = count;
814 this->max_count = count;
815 setStream(stream);
816 start_time = millis();
818 }
819
821 void setLogOutput(Print &out) { p_logout = &out; }
822
824 void setStream(Stream &io) override {
825 p_print = &io;
826 p_stream = &io;
827 };
828
830 void setOutput(Print &out) override { p_print = &out; }
831
833 size_t readBytes(uint8_t *data, size_t len) override {
835 return measure(p_stream->readBytes(data, len));
836 }
837
838 int available() override { return p_stream->available(); }
839
841 virtual size_t write(const uint8_t *data, size_t len) override {
843 return measure(p_print->write(data, len));
844 }
845
847 virtual int availableForWrite() override {
848 return p_print->availableForWrite();
849 }
850
853
856 if (frame_size == 0) return 0;
858 }
859
862
867
868 bool begin() override {
871 return AudioStream::begin();
872 }
873
876 return begin();
877 }
878
880 void setFrameSize(int size) { frame_size = size; }
881
884
885 void setName(const char *name) { this->name = name; }
886
889
892
895 if (bytesSinceBegin() == 0) return 0;
896 return static_cast<float>(timeSinceBegin()) / bytesSinceBegin() *
897 totalBytes;
898 }
899
902 if (bytesSinceBegin() == 0) return 0;
903 return estimatedTotalTimeFor(totalBytes) - timeSinceBegin();
904 }
905
909 bool is_regular_update = true;
910 if (pos < total_bytes_since_begin) {
911 begin();
912 is_regular_update = false;
913 }
915 return is_regular_update;
916 }
917
918 protected:
919 int max_count = 0;
920 int count = 0;
921 Stream *p_stream = nullptr;
922 Print *p_print = nullptr;
924 int total_bytes = 0;
926 int frame_size = 0;
928 Print *p_logout = nullptr;
929 bool report_bytes = false;
930 const char *name = "";
933
934 size_t measure(size_t len) {
935 count--;
936 total_bytes += len;
937
938 if (count <= 0) {
940 int time_diff = end_time - start_time; // in ms
941 if (time_diff > 0) {
943 printResult();
945 total_bytes = 0;
947 }
948 }
949 return len;
950 }
951
952 void printResult() {
953 char msg[70];
954 if (report_bytes || frame_size == 0) {
955 snprintf(msg, 70, "%s ==> Bytes per second: %d", name, bytes_per_second);
956 } else {
957 snprintf(msg, 70, "%s ==> Samples per second: %d", name,
959 }
960 if (p_logout != nullptr) {
961 p_logout->println(msg);
962 } else {
963 LOGI("%s", msg);
964 }
965 }
966};
967
975 public:
976 size_t total_size = 0;
977};
986 public:
987 ProgressStream() = default;
988
989 ProgressStream(Print &print) { setPrint(print); }
990
991 ProgressStream(Stream &stream) { setStream(stream); }
992
994 setStream(stream);
995 p_info_from = &stream;
996 }
997
999
1004
1005 void setStream(Stream &stream) override {
1006 p_stream = &stream;
1007 p_print = &stream;
1008 }
1009
1010 void setStream(Print &print) { p_print = &print; }
1011
1012 void setPrint(Print &print) { p_print = &print; }
1013
1014 bool begin() override {
1015 if (p_info_from != nullptr) {
1017 }
1018 return AudioStream::begin();
1019 }
1020
1023 bool begin(size_t len) {
1024 setSize(len);
1025 return begin();
1026 }
1027
1031 return begin();
1032 }
1033
1035 void setSize(size_t len) {
1036 total_processed = 0;
1038 }
1039
1041 size_t size() { return progress_info.total_size; }
1042
1044 size_t processedBytes() { return total_processed; }
1045
1047 size_t processedSecs() { return total_processed / byteRate(); }
1048
1051
1053 size_t totalSecs() { return totalBytes() / byteRate(); }
1054
1056 float percentage() {
1057 if (progress_info.total_size == 0) return 0;
1058 return 100.0 * total_processed / progress_info.total_size;
1059 }
1060
1062 size_t readBytes(uint8_t *data, size_t len) override {
1063 if (p_stream == nullptr) return 0;
1064 return measure(p_stream->readBytes(data, len));
1065 }
1066
1067 int available() override {
1068 if (p_stream == nullptr) return 0;
1069 return p_stream->available();
1070 }
1071
1073 virtual size_t write(const uint8_t *data, size_t len) override {
1074 if (p_print == nullptr) return 0;
1075 return measure(p_print->write(data, len));
1076 }
1077
1079 virtual int availableForWrite() override {
1080 if (p_print == nullptr) return 0;
1081 return p_print->availableForWrite();
1082 }
1083
1084 protected:
1086 Stream *p_stream = nullptr;
1087 Print *p_print = nullptr;
1090
1091 size_t measure(size_t len) {
1092 total_processed += len;
1093 return len;
1094 }
1095
1096 size_t byteRate() {
1098 int byte_rate = info.sample_rate * info.bits_per_sample * info.channels / 8;
1099 if (byte_rate == 0) {
1100 LOGE("Audio Info not defined");
1101 return 0;
1102 }
1103 return byte_rate;
1104 }
1105};
1106
1112struct ThrottleConfig : public AudioInfo {
1114 sample_rate = 44100;
1115 bits_per_sample = 16;
1116 channels = 2;
1117 }
1119};
1120
1128 public:
1129 Throttle() = default;
1130 Throttle(Print &out) { setOutput(out); }
1132
1134 void setStream(Stream &io) override {
1135 p_out = &io;
1136 p_in = &io;
1137 };
1138
1140 void setOutput(Print &out) override { p_out = &out; }
1141
1144 return c;
1145 }
1146
1148 LOGI("begin sample_rate: %d, channels: %d, bits: %d", (int)info.sample_rate,
1149 (int)info.channels, (int)info.bits_per_sample);
1150 this->info = cfg;
1151 this->cfg = cfg;
1152 return begin();
1153 }
1154
1156 LOGI("begin sample_rate: %d, channels: %d, bits: %d", (int)info.sample_rate,
1157 (int)info.channels, (int)info.bits_per_sample);
1158 this->info = info;
1159 this->cfg.copyFrom(info);
1160 return begin();
1161 }
1162
1163 bool begin() override {
1165 startDelay();
1166 return true;
1167 }
1168
1169 // (re)starts the timing
1170 void startDelay() {
1171 start_time = micros();
1172 sum_frames = 0;
1173 }
1174
1175 int availableForWrite() override {
1176 if (p_out) {
1177 return p_out->availableForWrite();
1178 }
1179 return DEFAULT_BUFFER_SIZE;
1180 }
1181
1182 size_t write(const uint8_t *data, size_t len) override {
1183 size_t result = p_out->write(data, len);
1184 delayBytes(len);
1185 return result;
1186 }
1187
1188 int available() override {
1189 if (p_in == nullptr) return 0;
1190 return p_in->available();
1191 }
1192
1193 size_t readBytes(uint8_t *data, size_t len) override {
1194 if (p_in == nullptr) {
1195 delayBytes(len);
1196 return 0;
1197 }
1198 size_t result = p_in->readBytes(data, len);
1199 delayBytes(len);
1200 return result;
1201 }
1202
1203 // delay
1205
1206 // delay
1207 void delayFrames(size_t frames) {
1208 sum_frames += frames;
1212 LOGD("wait us: %ld", static_cast<long>(waitUs));
1213 if (waitUs > 0) {
1214 int64_t waitMs = waitUs / 1000;
1215 if (waitMs > 0) delay(waitMs);
1216 delayMicroseconds(waitUs - (waitMs * 1000));
1217 } else {
1218 LOGD("negative delay!")
1219 }
1220 }
1221
1222 inline int64_t getDelayUs(uint64_t frames) {
1223 return (frames * 1000000) / cfg.sample_rate;
1224 }
1225
1226 inline int64_t getDelayMs(uint64_t frames) {
1227 return getDelayUs(frames) / 1000;
1228 }
1229
1231 return getDelayUs(frames) / 1000000l;
1232 }
1233
1234 protected:
1238 int frame_size = 0;
1239 Print *p_out = nullptr;
1240 Stream *p_in = nullptr;
1241};
1242
1252template <typename T=int16_t, typename SumT=float>
1253class InputMixer : public AudioStream {
1254 public:
1255 InputMixer() = default;
1256
1258 int add(Stream &in, int weight = 100) {
1259 streams.push_back(&in);
1260 weights.push_back(weight);
1262 return streams.indexOf(&in);
1263 }
1264
1266 bool set(int index, Stream &in) {
1267 if (index < size()) {
1268 streams[index] = &in;
1269 return true;
1270 } else {
1271 LOGE("Invalid index %d - max is %d", index, size() - 1);
1272 return false;
1273 }
1274 }
1275
1276 virtual bool begin(AudioInfo info) {
1279 LOGI("frame_size: %d", frame_size);
1280 return frame_size > 0;
1281 }
1282
1286 void setWeight(int index, int weight) {
1287 if (index < streams.size()) {
1288 weights[index] = weight;
1290 } else {
1291 LOGE("Invalid index %d - max is %d", index, size() - 1);
1292 }
1293 }
1294
1296 void end() override {
1297 streams.clear();
1298 weights.clear();
1299 gains.clear();
1300 result_vect.clear();
1301 current_vect.clear();
1302 total_weights = 0.0;
1303 }
1304
1306 int size() { return streams.size(); }
1307
1309 size_t readBytes(uint8_t *data, size_t len) override {
1310 if (total_weights == 0 || frame_size == 0 || len == 0) {
1311 LOGW("readBytes: %d", (int)len);
1312 return 0;
1313 }
1314
1316 len = min((int)len, availableBytes());
1317 }
1318
1319 int result_len = 0;
1320
1321 if (len > 0) {
1322 // result_len must be full frames
1323 result_len = (len / frame_size) * frame_size;;
1324 // replace sample based with vector based implementation
1325 // readBytesSamples((T*)data, result_len));
1327 }
1328 return result_len;
1329 }
1330
1334
1338
1340 bool remove(int idx) {
1341 if (idx < 0 || idx >= size()) {
1342 return false;
1343 }
1344 streams.erase(idx);
1345 weights.erase(idx);
1347 return true;
1348 }
1349
1351 bool remove() {
1352 bool rc = false;
1353 int idx = nextEmptyIndex();
1354 while (idx >= 0) {
1355 rc = true;
1356 streams.erase(idx);
1357 weights.erase(idx);
1358 idx = nextEmptyIndex();
1359 }
1361 return rc;
1362 }
1363
1365 int indexOf(Stream &stream) { return streams.indexOf(&stream); }
1366
1368 Stream *operator[](int idx) {
1369 if (idx < 0 || idx >= size()) return nullptr;
1370 return streams[idx];
1371 }
1372
1375 for (int i = 0; i < streams.size(); i++) {
1376 if (streams[i]->available() == 0) {
1377 return i;
1378 }
1379 }
1380 return -1;
1381 }
1382
1383 protected:
1388 int frame_size = 4;
1393
1396 int total = 0;
1397 for (int j = 0; j < weights.size(); j++) {
1398 total += weights[j];
1399 }
1400 total_weights = total;
1402 for (int j = 0; j < weights.size(); j++) {
1403 gains[j] = total_weights == 0 ? 0.0f : static_cast<float>(weights[j]) / total_weights;
1404 }
1405 }
1406
1408 int readBytesVector(T *p_data, int byteCount) {
1409 int samples = byteCount / sizeof(T);
1410 if (result_vect.size() < samples) result_vect.resize(samples);
1411 if (current_vect.size() < samples) current_vect.resize(samples);
1412 int stream_count = size();
1413 resultClear(samples);
1414 int samples_eff_max = 0;
1415 for (int j = 0; j < stream_count; j++) {
1416 if (weights[j] > 0) {
1417 int samples_eff =
1418 readSamples(streams[j], current_vect.data(), samples, retry_count);
1421 }
1422 }
1423 // copy result
1424 for (int j = 0; j < samples_eff_max; j++) {
1425 p_data[j] = static_cast<T>(result_vect[j]);
1426 }
1427 return samples_eff_max * sizeof(T);
1428 }
1429
1432 int result = DEFAULT_BUFFER_SIZE;
1433 for (int j = 0; j < size(); j++) {
1434 result = min(result, streams[j]->available());
1435 }
1436 return result;
1437 }
1438
1439 void resultAdd(float fact, int samples_eff) {
1440 // only accumulate samples that were actually read; tail is already zeroed
1441 for (int j = 0; j < samples_eff; j++) {
1442 result_vect[j] += static_cast<SumT>(current_vect[j] * fact);
1443 }
1444 }
1445
1446 void resultClear(int samples) {
1447 memset(result_vect.data(), 0, sizeof(SumT) * samples);
1448 }
1449};
1450
1460template <typename T>
1461class InputMerge : public AudioStream {
1462 public:
1464 InputMerge() = default;
1465
1469 InputMerge(Stream &left, Stream &right) {
1470 add(left, 1);
1471 add(right, 1);
1472 };
1473
1480
1481 virtual bool begin(AudioInfo info) {
1483 return begin();
1484 }
1485
1486 virtual bool begin() override {
1487 // make sure that we use the correct channel count
1489 return AudioStream::begin();
1490 }
1491
1493 size_t readBytes(uint8_t *data, size_t len) override {
1494 LOGD("readBytes: %d", (int)len);
1495 T *p_data = (T *)data;
1496 int result_len = MIN(available(), len);
1497 int frames = result_len / (sizeof(T) * total_channel_count);
1498 int result_idx = 0;
1499 for (int j = 0; j < frames; j++) {
1500 for (int i = 0; i < records.size(); i++) {
1501 for (int ch = 0; ch < records[i].channels; ch++) {
1502 p_data[result_idx++] =
1503 records[i].weight * readSample<T>(records[i].stream);
1504 }
1505 }
1506 }
1507 return result_idx * sizeof(T);
1508 }
1509
1511 void add(Stream &in, int channelCount, float weight = 1.0) {
1512 MergeRecord rec(&in, channelCount, weight);
1513 records.push_back(rec);
1515 }
1516
1519 void setWeight(int channel, float weight) {
1520 if (channel < channelCount()) {
1521 records[channel].weight = weight;
1522 } else {
1523 LOGE("Invalid channel %d - max is %d", channel, channelCount() - 1);
1524 }
1525 }
1526
1528 void end() override { records.clear(); }
1529
1532
1534 int available() override {
1535 int result = records[0].stream->available();
1536 for (int j = 1; j < channelCount(); j++) {
1537 int tmp = records[j].stream->available();
1538 if (tmp < result) {
1539 result = tmp;
1540 }
1541 }
1542 return result;
1543 }
1544
1545 protected:
1547 Stream *stream = nullptr;
1548 int channels = 0;
1549 float weight = 1.0;
1550 MergeRecord() = default;
1551 MergeRecord(Stream *str, int ch, float w) {
1552 stream = str;
1553 channels = ch;
1554 weight = w;
1555 }
1556 };
1559};
1560
1571 public:
1572 CallbackStream() = default;
1573
1576 CallbackStream(Stream &io, size_t (*cb_update)(uint8_t *data, size_t len)) {
1577 p_stream = &io;
1578 p_out = &io;
1580 }
1581
1583 CallbackStream(Print &out, size_t (*cb_update)(uint8_t *data, size_t len)) {
1584 p_out = &out;
1586 }
1587
1588 CallbackStream(size_t (*cb_read)(uint8_t *data, size_t len),
1589 size_t (*cb_write)(const uint8_t *data, size_t len)) {
1592 }
1593
1594 void setWriteCallback(size_t (*cb_write)(const uint8_t *data, size_t len)) {
1595 this->cb_write = cb_write;
1596 }
1597
1598 void setReadCallback(size_t (*cb_read)(uint8_t *data, size_t len)) {
1599 this->cb_read = cb_read;
1600 }
1601
1602 void setUpdateCallback(size_t (*cb_update)(uint8_t *data, size_t len)) {
1603 this->cb_update = cb_update;
1604 }
1605
1606 // callback result negative -> no change; callbeack result >=0 provides the
1607 // result
1608 void setAvailableCallback(int (*cb)()) { this->cb_available = cb; }
1609
1612 this->cb_audio_info = cb;
1613 }
1614
1616 void setAudioInfo(AudioInfo info) override {
1618 if (cb_audio_info != nullptr) {
1620 }
1621 }
1622
1623 virtual bool begin(AudioInfo info) {
1625 return begin();
1626 }
1627 virtual bool begin() override {
1628 active = true;
1629 return true;
1630 }
1631
1632 void end() override { active = false; }
1633
1634 int available() override {
1635 int result = AudioStream::available();
1636 // determine value from opional variable
1637 if (available_bytes >= 0) return available_bytes;
1638 // check if there is a callback
1639 if (cb_available == nullptr) return result;
1640 // determine value from callback
1642 if (tmp_available < 0) return result;
1643
1644 return tmp_available;
1645 }
1646
1647 size_t readBytes(uint8_t *data, size_t len) override {
1648 if (!active) return 0;
1649 // provide data from callback
1650 if (cb_read) {
1651 return cb_read(data, len);
1652 }
1653 // provide data from source
1654 size_t result = 0;
1655 if (p_stream) {
1656 result = p_stream->readBytes(data, len);
1657 }
1658 if (cb_update) {
1659 result = cb_update(data, result);
1660 }
1661 return result;
1662 }
1663
1664 size_t write(const uint8_t *data, size_t len) override {
1665 if (!active) return 0;
1666 // write to callback
1667 if (cb_write) {
1668 return cb_write(data, len);
1669 }
1670 // write to output
1671 if (p_out) {
1672 size_t result = len;
1673 if (cb_update) {
1674 result = cb_update((uint8_t *)data, len);
1675 }
1676 return p_out->write(data, result);
1677 }
1678 // no processing possible
1679 return 0;
1680 }
1681
1683 void setStream(Stream &in) override {
1684 p_stream = &in;
1685 p_out = &in;
1686 }
1687
1689 void setOutput(Print &out) override { p_out = &out; }
1690
1692 void setOutput(Stream &in) {
1693 p_stream = &in;
1694 p_out = &in;
1695 }
1696
1698 void setStream(Print &out) { p_out = &out; }
1699
1702
1703 protected:
1704 bool active = true;
1705 size_t (*cb_write)(const uint8_t *data, size_t len) = nullptr;
1706 size_t (*cb_read)(uint8_t *data, size_t len) = nullptr;
1707 size_t (*cb_update)(uint8_t *data, size_t len) = nullptr;
1709 int (*cb_available)() = nullptr;
1710 Stream *p_stream = nullptr;
1711 Print *p_out = nullptr;
1713};
1714
1722template <typename T = int16_t, class TF = float>
1724 public:
1725 FilteredStream() = default;
1728 this->channels = channels;
1729 setStream(stream);
1730 converter.setChannels(channels);
1731 }
1734 this->channels = channels;
1735 setOutput(stream);
1736 converter.setChannels(channels);
1737 }
1738
1739 virtual ~FilteredStream() { end(); }
1740
1741 void setStream(Stream &stream) override {
1742 p_stream = &stream;
1743 p_print = &stream;
1744 }
1745
1746 void setOutput(Print &stream) override { p_print = &stream; }
1747
1750 this->channels = info.channels;
1751 return begin();
1752 }
1753
1754 bool begin() override {
1755 if (channels == 0) {
1756 LOGE("channels must not be 0");
1757 return false;
1758 }
1759 converter.setChannels(channels);
1760 return AudioStream::begin();
1761 }
1762
1763 void end() override {
1765 }
1766
1767 virtual size_t write(const uint8_t *data, size_t len) override {
1768 if (p_print == nullptr) return 0;
1769 size_t result = converter.convert((uint8_t *)data, len);
1770 return p_print->write(data, result);
1771 }
1772
1773 size_t readBytes(uint8_t *data, size_t len) override {
1774 if (p_stream == nullptr) return 0;
1775 size_t result = p_stream->readBytes(data, len);
1776 result = converter.convert(data, result);
1777 return result;
1778 }
1779
1780 virtual int available() override {
1781 if (p_stream == nullptr) return 0;
1782 return p_stream->available();
1783 }
1784
1785 virtual int availableForWrite() override {
1786 if (p_print == nullptr) return 0;
1787 return p_print->availableForWrite();
1788 }
1789
1793 void setFilter(int channel, Filter<TF> *filter) {
1794 converter.setFilter(channel, filter);
1795 }
1796
1800 void setFilter(int channel, Filter<TF> &filter) {
1801 setFilter(channel, &filter);
1802 }
1803
1804 protected:
1805 int channels = 0;
1806 Stream *p_stream = nullptr;
1807 Print *p_print = nullptr;
1809};
1810
1812using ActivityCallback = void (*)(bool isActive);
1813
1824 public:
1825 VolumeMeter() = default;
1828 VolumeMeter(Print &print) { setOutput(print); }
1829 VolumeMeter(Stream &stream) { setStream(stream); }
1830
1833 return begin();
1834 }
1835
1836 bool begin() override {
1838 return true;
1839 }
1840
1841 void setAudioInfo(AudioInfo info) override {
1842 int channels = info.channels;
1843 LOGI("VolumeMeter::setAudioInfo: channels %d", channels);
1845 if (channels > 0) {
1846 volumes.resize(channels);
1847 volumes_tmp.resize(channels);
1848 sum.resize(channels);
1849 sum_tmp.resize(channels);
1850 }
1851 }
1852
1853 size_t write(const uint8_t *data, size_t len) override {
1854 updateVolumes(data, len);
1855 size_t result = len;
1856 if (p_out != nullptr) {
1857 result = p_out->write(data, len);
1858 }
1859 return result;
1860 }
1861
1862 size_t readBytes(uint8_t *data, size_t len) override {
1863 if (p_stream == nullptr) return 0;
1864 size_t result = p_stream->readBytes(data, len);
1865 updateVolumes((const uint8_t *)data, len);
1866 return result;
1867 }
1868
1871 float volume() { return f_volume; }
1872
1875 float volume(int channel) {
1876 if (volumes.size() == 0) {
1877 LOGE("begin not called!");
1878 return 0.0f;
1879 }
1880 if (channel >= volumes.size()) {
1881 LOGE("invalid channel %d", channel);
1882 return 0.0f;
1883 }
1884 return volumes[channel];
1885 }
1886
1891
1893 float volumeRatio(int channel) {
1895 }
1896
1898 float volumeDB() {
1899 // prevent infinite value
1900 if (volumeRatio() == 0) return -1000;
1901 return 20.0f * log10(volumeRatio());
1902 }
1903
1905 float volumeDB(int channel) {
1906 // prevent infinite value
1907 if (volumeRatio(channel) == 0) return -1000;
1908 return 20.0f * log10(volumeRatio(channel));
1909 }
1910
1912 float volumePercent() { return 100.0f * volumeRatio(); }
1913
1915 float volumePercent(int channel) { return 100.0f * volumeRatio(channel); }
1916
1918 float volumeAvg() {
1919 float total = 0;
1920 size_t count = 0;
1921 for (int j = 0; j < info.channels; j++) {
1922 total += sum[j];
1923 count += sample_count_per_channel;
1924 }
1925 return total / count;
1926 }
1927
1929 float volumeAvg(int channel) {
1930 return sum[channel] / sample_count_per_channel;
1931 }
1932
1934 void clear() {
1935 f_volume_tmp = 0;
1936 for (int j = 0; j < info.channels; j++) {
1937 volumes_tmp[j] = 0;
1938 sum_tmp[j] = 0;
1939 }
1940 }
1941
1946 void setActivityCallback(ActivityCallback callback, float threshold = 0.2, unsigned long duration_ms = 2000) {
1947 activity_callback = callback;
1948 activity_threshold = threshold;
1949 activity_duration_ms = duration_ms;
1950 activity_monitoring_enabled = (callback != nullptr);
1951 }
1952
1955 bool isActive() const {
1956 return is_active;
1957 }
1958
1961 setOutput((Print &)out);
1962 }
1965 setStream((Stream &)io);
1966 }
1967 void setOutput(Print &out) override { p_out = &out; }
1968 void setStream(Stream &io) override {
1969 p_out = &io;
1970 p_stream = &io;
1971 }
1972
1973 protected:
1974 float f_volume_tmp = 0;
1975 float f_volume = 0;
1980 Print *p_out = nullptr;
1981 Stream *p_stream = nullptr;
1983
1984 // Activity monitoring
1987 unsigned long activity_duration_ms = 0;
1989 bool is_active = false;
1990 unsigned long inactive_start_time = 0;
1991
1992 void updateVolumes(const uint8_t *data, size_t len) {
1993 if (data == nullptr || len == 0) return;
1994 clear();
1995 switch (info.bits_per_sample) {
1996 case 8:
1997 updateVolumesT<int8_t>(data, len);
1998 break;
1999 case 16:
2000 updateVolumesT<int16_t>(data, len);
2001 break;
2002 case 24:
2003 updateVolumesT<int24_t>(data, len);
2004 break;
2005 case 32:
2006 updateVolumesT<int32_t>(data, len);
2007 break;
2008 default:
2009 LOGE("Unsupported bits_per_sample: %d", info.bits_per_sample);
2010 break;
2011 }
2012 }
2013
2014 template <typename T>
2015 void updateVolumesT(const uint8_t *buffer, size_t size) {
2016 T *bufferT = (T *)buffer;
2017 int samplesCount = size / sizeof(T);
2019 for (int j = 0; j < samplesCount; j++) {
2020 float tmp = abs(static_cast<float>(bufferT[j]));
2021 updateVolume(tmp, j);
2022 }
2023 commit();
2024 }
2025
2026 void updateVolume(float tmp, int j) {
2027 if (tmp > f_volume_tmp) {
2028 f_volume_tmp = tmp;
2029 }
2030 if (volumes_tmp.size() > 0 && info.channels > 0) {
2031 int ch = j % info.channels;
2032 if (tmp > volumes_tmp[ch]) {
2033 volumes_tmp[ch] = tmp;
2034 sum_tmp[ch] = tmp;
2035 }
2036 }
2037 }
2038
2039 void commit() {
2041 for (int j = 0; j < info.channels; j++) {
2042 volumes[j] = volumes_tmp[j];
2043 sum[j] = sum_tmp[j];
2044 }
2046 }
2047
2049 if (!activity_monitoring_enabled || activity_callback == nullptr) return;
2050
2053 unsigned long current_time = millis();
2054
2055 if (above_threshold) {
2056 // Volume is above threshold - should be active
2057 if (!is_active) {
2058 is_active = true;
2059 activity_callback(true);
2060 }
2061 inactive_start_time = 0; // Reset inactive timer
2062 } else {
2063 // Volume is below threshold
2064 if (is_active) {
2065 // Currently active, check if we should transition to inactive
2066 if (inactive_start_time == 0) {
2067 // Start timing the inactive period
2068 inactive_start_time = current_time;
2069 } else if (current_time - inactive_start_time >= activity_duration_ms) {
2070 // Been below threshold long enough
2071 is_active = false;
2072 activity_callback(false);
2074 }
2075 }
2076 }
2077 }
2078};
2079
2080// legacy names
2084
2088
2102 public:
2152
2158
2166 return begin();
2167 }
2168
2173 bool begin() override {
2175 return true;
2176 }
2177
2186
2193 size_t write(const uint8_t *data, size_t len) override {
2194 size_t result = volume_meter.write(data, len);
2195 if (result > 0 && volume_meter.volumePercent() > limit_percent) {
2197 }
2198 return result;
2199 }
2200
2207 size_t readBytes(uint8_t *data, size_t len) override {
2208 size_t result = volume_meter.readBytes(data, len);
2209 if (result > 0 && volume_meter.volumePercent() > limit_percent) {
2211 }
2212 return result;
2213 }
2214
2219 void setOutput(Print &out) override { volume_meter.setOutput(out); }
2229 void setStream(Stream &io) override { volume_meter.setStream(io); }
2235
2241
2247 bool isActive(uint16_t time_ms = 1000) {
2248 return (millis() - time_over_last_volume_limit) < time_ms;
2249 }
2250
2251protected:
2255};
2256
2257#ifdef USE_TIMER
2272
2273// forward declaration: relevant only if use_timer == true
2274static void timerCallback(void *obj);
2285 friend void timerCallback(void *obj);
2286
2287 public:
2289
2291 TRACED();
2292 if (timer != nullptr) delete timer;
2293 if (buffer != nullptr) delete buffer;
2294 if (frame != nullptr) delete[] frame;
2295 }
2296
2302
2316
2320
2322 LOGD("%s: %s", LOG_METHOD,
2323 config.rx_tx_mode == RX_MODE ? "RX_MODE" : "TX_MODE");
2324 this->cfg = config;
2325 this->frameCallback = config.callback;
2326 if (cfg.use_timer) {
2328 frame = new uint8_t[frameSize];
2330 timer = new TimerAlarmRepeating();
2332 if (cfg.timer_id >= 0) {
2334 }
2336 LOGI("sample_rate: %u -> time: %u milliseconds",
2337 (unsigned int)cfg.sample_rate, (unsigned int)time);
2340 }
2341
2343 active = true;
2344 }
2345
2347 bool begin() {
2348 TRACED();
2349 if (this->frameCallback != nullptr) {
2350 if (cfg.use_timer) {
2351 timer->begin(timerCallback, time, TimeUnit::US);
2352 }
2353 active = true;
2354 }
2355 return active;
2356 }
2357
2359 void end() {
2360 TRACED();
2361 if (cfg.use_timer) {
2362 timer->end();
2363 }
2364 active = false;
2365 }
2366
2369
2370 protected:
2372 bool active = false;
2374 // below only relevant with timer
2377 uint8_t *frame = nullptr;
2380 unsigned long lastTimestamp = 0u;
2383
2384 // used for audio sink
2385 virtual size_t writeExt(const uint8_t *data, size_t len) override {
2386 if (!active) return 0;
2387 TRACED();
2388 size_t result = 0;
2389 if (!cfg.use_timer) {
2390 result = frameCallback((uint8_t *)data, len);
2391 } else {
2392 result = buffer->writeArray((uint8_t *)data, len);
2393 }
2394 if (++printCount % 10000 == 0) printSampleRate();
2395 return result;
2396 }
2397
2398 // used for audio source
2399 virtual size_t readExt(uint8_t *data, size_t len) override {
2400 if (!active) return 0;
2401 TRACED();
2402
2403 size_t result = 0;
2404 if (!cfg.use_timer) {
2405 result = frameCallback(data, len);
2406 } else {
2407 result = buffer->readArray(data, len);
2408 }
2409 if (++printCount % 10000 == 0) printSampleRate();
2410 return result;
2411 }
2412
2414 virtual void measureSampleRate() {
2415 unsigned long ms = millis();
2416 if (lastTimestamp > 0u) {
2418 if (diff > 0) {
2419 uint16_t rate = 1 * 1000 / diff;
2420
2421 if (currentRateValue == 0) {
2422 currentRateValue = rate;
2423 } else {
2424 currentRateValue = (currentRateValue + rate) / 2;
2425 }
2426 }
2427 }
2428 lastTimestamp = ms;
2429 }
2430
2432 virtual void printSampleRate() {
2433 LOGI("effective sample rate: %u", (unsigned int)currentRateValue);
2434 if (cfg.adapt_sample_rate &&
2435 abs((int)currentRateValue - (int)cfg.sample_rate) > 200) {
2438 }
2439 }
2440};
2441
2442// relevant only if use_timer == true
2445 if (src != nullptr) {
2446 // LOGD("%s: %s", LOG_METHOD, src->cfg.rx_tx_mode==RX_MODE ?
2447 // "RX_MODE":"TX_MODE");
2448 if (src->cfg.rx_tx_mode == RX_MODE) {
2449 // input
2450 uint16_t available_bytes = src->frameCallback(src->frame, src->frameSize);
2451 uint16_t buffer_available = src->buffer->availableForWrite();
2452 if (buffer_available < available_bytes) {
2453 // if buffer is full make space
2454 uint16_t to_clear = available_bytes - buffer_available;
2455 uint8_t tmp[to_clear];
2456 src->buffer->readArray(tmp, to_clear);
2457 }
2458 if (src->buffer->writeArray(src->frame, available_bytes) !=
2459 available_bytes) {
2460 assert(false);
2461 }
2462 } else {
2463 // output
2464 if (src->buffer != nullptr && src->frame != nullptr &&
2465 src->frameSize > 0) {
2466 uint16_t available_bytes =
2467 src->buffer->readArray(src->frame, src->frameSize);
2468 if (available_bytes !=
2469 src->frameCallback(src->frame, available_bytes)) {
2470 LOGE("data underflow");
2471 }
2472 }
2473 }
2474 src->measureSampleRate();
2475 }
2476}
2477
2478#endif
2479
2480} // 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:64
#define MIN(A, B)
Definition AudioTypes.h:17
void loop()
#define DEFAULT_BUFFER_SIZE
Definition avr.h:20
#define assert(T)
Definition avr.h:10
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:178
virtual void addNotifyAudioChange(AudioInfoSupport &bi)
Adds target to be notified about audio changes.
Definition AudioTypes.h:153
Supports changes to the sampling rate, bits and channels.
Definition AudioTypes.h:135
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:2101
void setOutput(Print &out) override
Set the output target.
Definition AudioStreams.h:2219
void setStream(AudioStream &io)
Set the input stream.
Definition AudioStreams.h:2234
AudioInputMonitor(AudioOutput &ao, uint8_t limitPercent=20)
Construct a new AudioInputMonitor with an output.
Definition AudioStreams.h:2125
uint8_t limit_percent
Threshold percent.
Definition AudioStreams.h:2253
AudioInputMonitor(Print &print, uint8_t limitPercent=20)
Construct a new AudioInputMonitor with a Print output.
Definition AudioStreams.h:2134
bool isActive(uint16_t time_ms=1000)
Returns true if the volume exceeded the limit during the last period.
Definition AudioStreams.h:2247
VolumeMeter volume_meter
Volume calculation.
Definition AudioStreams.h:2252
AudioInputMonitor(uint8_t limitPercent=20)
Construct a new AudioInputMonitor with a volume limit in percent.
Definition AudioStreams.h:2107
void setOutput(AudioOutput &out)
Set the output target.
Definition AudioStreams.h:2224
size_t readBytes(uint8_t *data, size_t len) override
Read audio data from the monitor (same as VolumeMeter)
Definition AudioStreams.h:2207
uint64_t time_over_last_volume_limit
Last over-limit time (ms)
Definition AudioStreams.h:2254
VolumeMeter & getVolumeMeter()
Access the underlying VolumeMeter.
Definition AudioStreams.h:2240
size_t write(const uint8_t *data, size_t len) override
Write audio data to the monitor (same as VolumeMeter)
Definition AudioStreams.h:2193
uint8_t limitPercent() const
Get the current volume threshold as percent.
Definition AudioStreams.h:2157
AudioInputMonitor(Stream &stream, uint8_t limitPercent=20)
Construct a new AudioInputMonitor with a Stream input.
Definition AudioStreams.h:2143
bool begin() override
Begin processing with the current audio information.
Definition AudioStreams.h:2173
void setAudioInfo(AudioInfo info) override
Set the audio information.
Definition AudioStreams.h:2182
void setStream(Stream &io) override
Set the input stream.
Definition AudioStreams.h:2229
void setLimitPercent(uint8_t percent)
Set the volume threshold as percent.
Definition AudioStreams.h:2151
bool begin(AudioInfo info)
Begin processing with the given audio information.
Definition AudioStreams.h:2164
AudioInputMonitor(AudioStream &as, uint8_t limitPercent=20)
Construct a new AudioInputMonitor with an input stream.
Definition AudioStreams.h:2116
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:123
AudioInfo info
Definition BaseStream.h:174
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition BaseStream.h:131
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition BaseStream.h:154
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:242
virtual int readArray(T data[], int len)
reads multiple values
Definition Buffers.h:33
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition Buffers.h:55
bool isEmpty()
Definition Buffers.h:86
Abstract Base class for Converters A converter is processing the data in the indicated array.
Definition BaseConverter.h:24
virtual size_t convert(uint8_t *src, size_t size)=0
virtual bool begin()
Definition BaseStream.h:43
virtual void end()
Definition BaseStream.h:44
virtual int available() override
Definition BaseStream.h:58
The Arduino Stream supports operations on single characters. This is usually not the best way to push...
Definition AudioStreams.h:566
void flush() override
empties the buffer
Definition AudioStreams.h:623
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioStreams.h:597
size_t minReadBufferSize
Definition AudioStreams.h:689
virtual size_t readExt(uint8_t *data, size_t len)
Definition AudioStreams.h:715
void setMinUnbufferedReadSize(size_t size)
Definition AudioStreams.h:683
size_t write(uint8_t c) override
writes a byte to the buffer
Definition AudioStreams.h:605
Stream * p_in
Definition AudioStreams.h:688
virtual size_t writeExt(const uint8_t *data, size_t len)
Definition AudioStreams.h:712
size_t readBytes(uint8_t *data, size_t len) override
Use this method !!
Definition AudioStreams.h:652
int peek() override
peeks a byte - to be avoided
Definition AudioStreams.h:642
void refill()
refills the buffer with data from the source
Definition AudioStreams.h:692
BufferedStream(Print &out, size_t buffer_size=1024)
Definition AudioStreams.h:573
int available() override
Returns the available bytes.
Definition AudioStreams.h:670
void setStream(Print &out)
Definition AudioStreams.h:598
size_t write(const uint8_t *data, size_t len) override
Use this method: write an array.
Definition AudioStreams.h:613
size_t peekBytes(uint8_t *data, size_t len)
Provides data w/o consuming.
Definition AudioStreams.h:662
Print * p_out
Definition AudioStreams.h:687
BufferedStream(size_t buffer_size)
Definition AudioStreams.h:568
SingleBuffer< uint8_t > buffer
Definition AudioStreams.h:686
void clear()
Clears all the data in the buffer.
Definition AudioStreams.h:676
int read() override
reads a byte - to be avoided
Definition AudioStreams.h:632
BufferedStream(Stream &io, size_t buffer_size=1024)
Definition AudioStreams.h:579
void refill(size_t len)
refill only if not enough data
Definition AudioStreams.h:707
void resize(int size)
Resize the buffer.
Definition AudioStreams.h:679
void setStream(Stream &io) override
Defines/Changes the input & output.
Definition AudioStreams.h:599
BufferedStream(size_t buffer_size, Print &out)
Definition AudioStreams.h:585
BufferedStream(size_t buffer_size, Stream &io)
Definition AudioStreams.h:591
CallbackStream: A Stream that allows to register callback methods for accessing and providing data....
Definition AudioStreams.h:1570
bool active
Definition AudioStreams.h:1704
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioStreams.h:1689
void setOutput(Stream &in)
same as setStream
Definition AudioStreams.h:1692
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:1583
size_t(* cb_read)(uint8_t *data, size_t len)
Definition AudioStreams.h:1706
virtual bool begin(AudioInfo info)
Definition AudioStreams.h:1623
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:1647
virtual bool begin() override
Definition AudioStreams.h:1627
void setReadCallback(size_t(*cb_read)(uint8_t *data, size_t len))
Definition AudioStreams.h:1598
void end() override
Definition AudioStreams.h:1632
int available() override
Definition AudioStreams.h:1634
void setStream(Print &out)
same as set Output
Definition AudioStreams.h:1698
size_t(* cb_write)(const uint8_t *data, size_t len)
Definition AudioStreams.h:1705
size_t write(const uint8_t *data, size_t len) override
Definition AudioStreams.h:1664
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:1588
void setAvailableCallback(int(*cb)())
Definition AudioStreams.h:1608
Stream * p_stream
Definition AudioStreams.h:1710
void(* cb_audio_info)(AudioInfo info)
Definition AudioStreams.h:1708
void setAvailable(int val)
optioinally define available bytes for next read
Definition AudioStreams.h:1701
Print * p_out
Definition AudioStreams.h:1711
int available_bytes
Definition AudioStreams.h:1712
int(* cb_available)()
Definition AudioStreams.h:1709
void setAudioInfo(AudioInfo info) override
Updates the audio info and calls the callback.
Definition AudioStreams.h:1616
void setStream(Stream &in) override
Defines/Changes the input & output.
Definition AudioStreams.h:1683
size_t(* cb_update)(uint8_t *data, size_t len)
Definition AudioStreams.h:1707
CallbackStream(Stream &io, size_t(*cb_update)(uint8_t *data, size_t len))
Definition AudioStreams.h:1576
void setWriteCallback(size_t(*cb_write)(const uint8_t *data, size_t len))
Definition AudioStreams.h:1594
void setAudioInfoCallback(void(*cb)(AudioInfo info))
defines the callback to receive the actual audio info
Definition AudioStreams.h:1611
void setUpdateCallback(size_t(*cb_update)(uint8_t *data, size_t len))
Definition AudioStreams.h:1602
Converter for n Channels which applies the indicated Filter.
Definition BaseConverter.h:1690
Both the data of the read or write operations will be converted with the help of the indicated conver...
Definition AudioStreams.h:729
BaseConverter * p_converter
Definition AudioStreams.h:784
void setConverter(BaseConverter &cnv)
Definition AudioStreams.h:756
ConverterStream(Stream &stream, BaseConverter &converter)
Definition AudioStreams.h:735
ConverterStream(BaseConverter &converter)
Definition AudioStreams.h:733
virtual int availableForWrite()
Definition AudioStreams.h:758
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:769
void setStream(Stream &stream)
Defines/Changes the input & output.
Definition AudioStreams.h:745
Stream * p_stream
Definition AudioStreams.h:782
virtual size_t write(const uint8_t *data, size_t len)
Definition AudioStreams.h:760
Print * p_out
Definition AudioStreams.h:783
void setOutput(Print &out)
Defines/Changes the output target.
Definition AudioStreams.h:751
ConverterStream(Print &out, BaseConverter &converter)
Definition AudioStreams.h:740
virtual int available() override
Returns the available bytes in the buffer: to be avoided.
Definition AudioStreams.h:776
Abstract filter interface definition;.
Definition Filter.h:28
Stream to which we can apply Filters for each channel. The filter might change the result size!
Definition AudioStreams.h:1723
virtual size_t write(const uint8_t *data, size_t len) override
Definition AudioStreams.h:1767
void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioStreams.h:1741
int channels
Definition AudioStreams.h:1805
ConverterNChannels< T, TF > converter
Definition AudioStreams.h:1808
virtual ~FilteredStream()
Definition AudioStreams.h:1739
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:1773
void setOutput(Print &stream) override
Defines/Changes the output target.
Definition AudioStreams.h:1746
void setFilter(int channel, Filter< TF > &filter)
Definition AudioStreams.h:1800
void end() override
Definition AudioStreams.h:1763
virtual int availableForWrite() override
Definition AudioStreams.h:1785
FilteredStream(Stream &stream, int channels)
Definition AudioStreams.h:1727
Stream * p_stream
Definition AudioStreams.h:1806
FilteredStream(Stream &stream)
Definition AudioStreams.h:1726
void setFilter(int channel, Filter< TF > *filter)
Definition AudioStreams.h:1793
FilteredStream(Print &stream, int channels)
Definition AudioStreams.h:1733
bool begin() override
Definition AudioStreams.h:1754
FilteredStream(Print &stream)
Definition AudioStreams.h:1732
Print * p_print
Definition AudioStreams.h:1807
bool begin(AudioInfo info)
Definition AudioStreams.h:1748
virtual int available() override
Definition AudioStreams.h:1780
Source for reading generated tones. Please note.
Definition AudioStreams.h:454
bool active
Definition AudioStreams.h:551
void flush() override
Definition AudioStreams.h:545
void setInput(SoundGenerator< T > &generator)
Definition AudioStreams.h:463
const char * source_not_defined_error
Definition AudioStreams.h:555
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:548
size_t readBytes(uint8_t *data, size_t len) override
privide the data as byte stream
Definition AudioStreams.h:529
void end() override
stop the processing
Definition AudioStreams.h:509
AudioInfo defaultConfig()
Definition AudioStreams.h:467
GeneratedSoundStream(SoundGenerator< T > &generator)
Definition AudioStreams.h:458
bool isActive()
Definition AudioStreams.h:538
bool begin() override
start the processing
Definition AudioStreams.h:483
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioStreams.h:517
int buffer_size
Definition AudioStreams.h:553
bool begin(AudioInfo cfg)
start the processing
Definition AudioStreams.h:496
virtual int available() override
This is unbounded so we just return the buffer size.
Definition AudioStreams.h:526
SoundGenerator< T > * p_generator
Definition AudioStreams.h:552
Merges multiple input streams. So if you provide 2 mono channels you get a stereo signal as result wi...
Definition AudioStreams.h:1461
InputMerge()=default
Default constructor.
int total_channel_count
Definition AudioStreams.h:1558
virtual bool begin(AudioInfo info)
Definition AudioStreams.h:1481
size_t readBytes(uint8_t *data, size_t len) override
Provides the data from all streams mixed together.
Definition AudioStreams.h:1493
virtual bool begin() override
Definition AudioStreams.h:1486
Vector< MergeRecord > records
Definition AudioStreams.h:1557
void end() override
Remove all input streams.
Definition AudioStreams.h:1528
int available() override
Provides the min available data from all streams.
Definition AudioStreams.h:1534
void add(Stream &in, int channelCount, float weight=1.0)
Adds a new input stream with 1 channel.
Definition AudioStreams.h:1511
void setWeight(int channel, float weight)
Definition AudioStreams.h:1519
int channelCount()
Number of channels to which are mixed together = number of result channels.
Definition AudioStreams.h:1531
InputMerge(Stream &left, Stream &right)
Constructor for stereo signal from to mono input stream.
Definition AudioStreams.h:1469
AudioInfo audioInfo() override
Provides the audio info with the total channel count.
Definition AudioStreams.h:1475
MixerStream is mixing the input from Multiple Input Streams. All streams must have the same audo form...
Definition AudioStreams.h:1253
bool limit_available_data
Definition AudioStreams.h:1389
bool remove()
Removes all streams which have no data available.
Definition AudioStreams.h:1351
Vector< float > gains
Definition AudioStreams.h:1386
int nextEmptyIndex()
Provides you the index of the next empty stream. -1 when none is found.
Definition AudioStreams.h:1374
virtual bool begin(AudioInfo info)
Definition AudioStreams.h:1276
int indexOf(Stream &stream)
Provides the actual index of the stream.
Definition AudioStreams.h:1365
bool set(int index, Stream &in)
Replaces a stream at the indicated index.
Definition AudioStreams.h:1266
size_t readBytes(uint8_t *data, size_t len) override
Provides the data from all streams mixed together.
Definition AudioStreams.h:1309
void recalculateWeights()
Recalculate the weights.
Definition AudioStreams.h:1395
int add(Stream &in, int weight=100)
Adds a new input stream and returns it's actual index position.
Definition AudioStreams.h:1258
void resultAdd(float fact, int samples_eff)
Definition AudioStreams.h:1439
void end() override
Remove all input streams.
Definition AudioStreams.h:1296
bool remove(int idx)
Removes a stream by index position.
Definition AudioStreams.h:1340
Vector< int > weights
Definition AudioStreams.h:1385
int retry_count
Definition AudioStreams.h:1390
Vector< Stream * > streams
Definition AudioStreams.h:1384
int availableBytes()
Provides the available bytes from the first stream with data.
Definition AudioStreams.h:1431
void setLimitToAvailableData(bool flag)
Definition AudioStreams.h:1333
Vector< SumT > result_vect
Definition AudioStreams.h:1391
void setRetryCount(int retry)
Definition AudioStreams.h:1337
int total_weights
Definition AudioStreams.h:1387
Vector< T > current_vect
Definition AudioStreams.h:1392
int readBytesVector(T *p_data, int byteCount)
mixing using a vector of samples
Definition AudioStreams.h:1408
void resultClear(int samples)
Definition AudioStreams.h:1446
void setWeight(int index, int weight)
Definition AudioStreams.h:1286
int frame_size
Definition AudioStreams.h:1388
Stream * operator[](int idx)
Provides the stream pointer at the indicated index.
Definition AudioStreams.h:1368
int size()
Number of stremams to which are mixed together.
Definition AudioStreams.h:1306
Class which measures the thruput.
Definition AudioStreams.h:793
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:841
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioStreams.h:830
uint32_t estimatedTotalTimeFor(uint32_t totalBytes)
Provides the estimated runtime in milliseconds for the indicated total.
Definition AudioStreams.h:894
bool report_bytes
Definition AudioStreams.h:929
uint32_t ms_at_begin
Definition AudioStreams.h:931
uint32_t start_time
Definition AudioStreams.h:923
uint32_t timeSinceBegin()
Provides the time in ms since the last call of begin()
Definition AudioStreams.h:888
size_t readBytes(uint8_t *data, size_t len) override
Provides the data from all streams mixed together.
Definition AudioStreams.h:833
MeasuringStream(Stream &stream, int count=10, Print *logOut=nullptr)
Definition AudioStreams.h:812
int framesPerSecond()
Returns the actual thrughput in frames (samples) per second.
Definition AudioStreams.h:855
uint32_t bytesSinceBegin()
Provides the total processed bytes since the last call of begin()
Definition AudioStreams.h:891
int available() override
Definition AudioStreams.h:838
virtual int availableForWrite() override
Provides the nubmer of bytes we can write.
Definition AudioStreams.h:847
MeasuringStream(int count=10, Print *logOut=nullptr)
Definition AudioStreams.h:795
uint32_t total_bytes_since_begin
Definition AudioStreams.h:932
Stream * p_stream
Definition AudioStreams.h:921
size_t measure(size_t len)
Definition AudioStreams.h:934
int total_bytes
Definition AudioStreams.h:924
void setFrameSize(int size)
Trigger reporting in frames (=samples) per second.
Definition AudioStreams.h:880
int max_count
Definition AudioStreams.h:919
void setReportBytes(bool flag)
Report in bytes instead of samples.
Definition AudioStreams.h:883
uint32_t estimatedOpenTimeFor(uint32_t totalBytes)
Provides the estimated time from now to the end in ms.
Definition AudioStreams.h:901
const char * name
Definition AudioStreams.h:930
void setLogOutput(Print &out)
Defines the logging output.
Definition AudioStreams.h:821
int bytes_per_second
Definition AudioStreams.h:925
MeasuringStream(Print &print, int count=10, Print *logOut=nullptr)
Definition AudioStreams.h:804
bool setProcessedBytes(uint32_t pos)
Definition AudioStreams.h:908
Print * p_logout
Definition AudioStreams.h:928
void printResult()
Definition AudioStreams.h:952
void setName(const char *name)
Definition AudioStreams.h:885
uint32_t startTime()
Provides the time when the last measurement was started.
Definition AudioStreams.h:861
bool begin() override
Definition AudioStreams.h:868
Print * p_print
Definition AudioStreams.h:922
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition AudioStreams.h:863
int count
Definition AudioStreams.h:920
int frame_size
Definition AudioStreams.h:926
void setStream(Stream &io) override
Defines/Changes the input & output.
Definition AudioStreams.h:824
bool begin(AudioInfo info)
Definition AudioStreams.h:874
NullStream null
Definition AudioStreams.h:927
int bytesPerSecond()
Returns the actual thrughput in bytes per second.
Definition AudioStreams.h:852
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:343
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition AudioTypes.h:301
Definition NoArduino.h:62
virtual int availableForWrite()
Definition NoArduino.h:134
virtual size_t write(const uint8_t *data, size_t len)
Definition NoArduino.h:126
virtual void flush()
Definition NoArduino.h:136
Generic calss to measure the the total bytes which were processed in order to calculate the progress ...
Definition AudioStreams.h:985
bool begin(size_t len)
Definition AudioStreams.h:1023
ProgressStream(Print &print)
Definition AudioStreams.h:989
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:1073
bool begin(ProgressStreamInfo info)
Definition AudioStreams.h:1028
size_t size()
Provides the current total size (defined by setSize)
Definition AudioStreams.h:1041
void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioStreams.h:1005
ProgressStreamInfo & defaultConfig()
Definition AudioStreams.h:998
size_t total_processed
Definition AudioStreams.h:1089
size_t totalSecs()
Converts the totalBytes() to seconds.
Definition AudioStreams.h:1053
ProgressStreamInfo progress_info
Definition AudioStreams.h:1085
size_t byteRate()
Definition AudioStreams.h:1096
size_t readBytes(uint8_t *data, size_t len) override
Provides the data from all streams mixed together.
Definition AudioStreams.h:1062
size_t processedBytes()
Provides the number of processed bytes.
Definition AudioStreams.h:1044
void setPrint(Print &print)
Definition AudioStreams.h:1012
int available() override
Definition AudioStreams.h:1067
void setSize(size_t len)
Updates the total size and restarts the percent calculation.
Definition AudioStreams.h:1035
virtual int availableForWrite() override
Provides the nubmer of bytes we can write.
Definition AudioStreams.h:1079
Stream * p_stream
Definition AudioStreams.h:1086
size_t measure(size_t len)
Definition AudioStreams.h:1091
float percentage()
Provides the processed percentage: If no size has been defined we return 0.
Definition AudioStreams.h:1056
AudioInfoSupport * p_info_from
Definition AudioStreams.h:1088
size_t processedSecs()
Provides the number of processed seconds.
Definition AudioStreams.h:1047
bool begin() override
Definition AudioStreams.h:1014
Print * p_print
Definition AudioStreams.h:1087
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition AudioStreams.h:1000
size_t totalBytes()
Provides the total_size provided in the configuration.
Definition AudioStreams.h:1050
void setStream(Print &print)
Definition AudioStreams.h:1010
ProgressStream(Stream &stream)
Definition AudioStreams.h:991
ProgressStream(AudioStream &stream)
Definition AudioStreams.h:993
Configuration for ProgressStream.
Definition AudioStreams.h:974
size_t total_size
Definition AudioStreams.h:976
Implements a typed Ringbuffer.
Definition Buffers.h:341
bool peek(T &result) override
peeks the actual entry from the buffer
Definition Buffers.h:361
bool read(T &result) override
reads a single value
Definition Buffers.h:348
virtual int availableForWrite() override
provides the number of entries that are available to write
Definition Buffers.h:413
virtual bool write(T data) override
write add an entry to the buffer
Definition Buffers.h:391
virtual size_t size() override
Returns the maximum capacity of the buffer.
Definition Buffers.h:428
virtual bool resize(int len)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:418
virtual int available() override
provides the number of entries that are available to read
Definition Buffers.h:410
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:172
size_t setAvailable(size_t available_size)
Definition Buffers.h:296
void trim()
Moves the unprocessed data to the beginning of the buffer.
Definition Buffers.h:273
bool write(T sample) override
write add an entry to the buffer
Definition Buffers.h:206
bool peek(T &result) override
peeks the actual entry from the buffer
Definition Buffers.h:224
bool read(T &result) override
reads a single value
Definition Buffers.h:215
int available() override
provides the number of entries that are available to read
Definition Buffers.h:233
int availableForWrite() override
provides the number of entries that are available to write
Definition Buffers.h:238
T * address() override
Provides address to beginning of the buffer.
Definition Buffers.h:281
bool isFull() override
checks if the buffer is full
Definition Buffers.h:240
bool resize(int size)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:305
int peekArray(uint8_t *data, int len)
Definition Buffers.h:242
void reset() override
clears the buffer
Definition Buffers.h:286
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 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
Definition NoArduino.h:142
virtual size_t readBytes(uint8_t *data, size_t len)
Definition NoArduino.h:147
virtual int available()
Definition NoArduino.h:146
Throttle the sending or receiving of the audio data to limit it to the indicated sample rate.
Definition AudioStreams.h:1127
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioStreams.h:1140
uint32_t sum_frames
Definition AudioStreams.h:1236
Throttle(Print &out)
Definition AudioStreams.h:1130
Stream * p_in
Definition AudioStreams.h:1240
Throttle(Stream &io)
Definition AudioStreams.h:1131
uint32_t start_time
Definition AudioStreams.h:1235
ThrottleConfig cfg
Definition AudioStreams.h:1237
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:1193
int64_t getDelayMs(uint64_t frames)
Definition AudioStreams.h:1226
int available() override
Definition AudioStreams.h:1188
size_t write(const uint8_t *data, size_t len) override
Definition AudioStreams.h:1182
int availableForWrite() override
Definition AudioStreams.h:1175
void delayFrames(size_t frames)
Definition AudioStreams.h:1207
void delayBytes(size_t bytes)
Definition AudioStreams.h:1204
bool begin(ThrottleConfig cfg)
Definition AudioStreams.h:1147
Print * p_out
Definition AudioStreams.h:1239
int64_t getDelayUs(uint64_t frames)
Definition AudioStreams.h:1222
int64_t getDelaySec(uint64_t frames)
Definition AudioStreams.h:1230
void startDelay()
Definition AudioStreams.h:1170
bool begin() override
Definition AudioStreams.h:1163
int frame_size
Definition AudioStreams.h:1238
void setStream(Stream &io) override
Defines/Changes the input & output.
Definition AudioStreams.h:1134
ThrottleConfig defaultConfig()
Definition AudioStreams.h:1142
bool begin(AudioInfo info)
Definition AudioStreams.h:1155
Common Interface definition for TimerAlarmRepeating.
Definition AudioTimer.h:29
virtual void setTimer(int timer)
Definition AudioTimer.h:60
virtual void setTimerFunction(TimerFunction function=DirectTimerCallback)
Definition AudioTimer.h:62
void setCallbackParameter(void *obj)
Definition AudioTimer.h:56
bool begin(repeating_timer_callback_t callback_f, uint32_t time, TimeUnit unit=MS)
Definition AudioTimer.h:43
bool end()
Definition AudioTimer.h:51
Callback driven Audio Source (rx_tx_mode==RX_MODE) or Audio Sink (rx_tx_mode==TX_MODE)....
Definition AudioStreams.h:2284
bool active
Definition AudioStreams.h:2372
void begin(TimerCallbackAudioStreamInfo config)
Definition AudioStreams.h:2321
TimerCallbackAudioStream()
Definition AudioStreams.h:2288
TimerCallbackAudioStreamInfo audioInfoExt()
Provides the current audio information.
Definition AudioStreams.h:2318
uint16_t currentSampleRate()
Provides the effective sample rate.
Definition AudioStreams.h:2368
virtual size_t writeExt(const uint8_t *data, size_t len) override
Definition AudioStreams.h:2385
uint16_t frameSize
Definition AudioStreams.h:2378
TimerCallbackAudioStreamInfo defaultConfig()
Provides the default configuration.
Definition AudioStreams.h:2298
bool begin()
Restart the processing.
Definition AudioStreams.h:2347
uint32_t currentRateValue
Definition AudioStreams.h:2381
friend void timerCallback(void *obj)
Definition AudioStreams.h:2443
AudioInfo audioInfo()
provides the actual input AudioInfo
Definition AudioStreams.h:2319
virtual void measureSampleRate()
calculates the effective sample rate
Definition AudioStreams.h:2414
virtual void setAudioInfo(AudioInfo info)
updates the audio information
Definition AudioStreams.h:2304
virtual void printSampleRate()
log and update effective sample rate
Definition AudioStreams.h:2432
virtual size_t readExt(uint8_t *data, size_t len) override
Definition AudioStreams.h:2399
RingBuffer< uint8_t > * buffer
Definition AudioStreams.h:2376
~TimerCallbackAudioStream()
Definition AudioStreams.h:2290
void end()
Stops the processing.
Definition AudioStreams.h:2359
unsigned long lastTimestamp
Definition AudioStreams.h:2380
TimerAlarmRepeating * timer
Definition AudioStreams.h:2375
TimerCallbackAudioStreamInfo cfg
Definition AudioStreams.h:2371
uint32_t time
Definition AudioStreams.h:2379
uint32_t printCount
Definition AudioStreams.h:2382
uint8_t * frame
Definition AudioStreams.h:2377
uint16_t(* frameCallback)(uint8_t *data, uint16_t len)
Definition AudioStreams.h:2373
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
void push_back(T &&value)
Definition Vector.h:182
bool resize(int newSize, T value)
Definition Vector.h:266
void clear()
Definition Vector.h:176
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:1823
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioStreams.h:1967
void setStream(AudioStream &io)
Defines/Changes the input & output and registers for audio change notifications.
Definition AudioStreams.h:1963
float volumeRatio()
Volume Ratio: max amplitude is 1.0.
Definition AudioStreams.h:1888
float volumeAvg(int channel)
Average volume of indicated channel.
Definition AudioStreams.h:1929
float volume()
Definition AudioStreams.h:1871
Vector< float > sum
Definition AudioStreams.h:1978
size_t sample_count_per_channel
Definition AudioStreams.h:1982
Vector< float > volumes_tmp
Definition AudioStreams.h:1977
VolumeMeter(AudioOutput &ao)
Definition AudioStreams.h:1827
bool isActive() const
Definition AudioStreams.h:1955
bool is_active
Definition AudioStreams.h:1989
unsigned long activity_duration_ms
Definition AudioStreams.h:1987
float volumePercent()
Volume in %: max amplitude is 100.
Definition AudioStreams.h:1912
void updateVolumes(const uint8_t *data, size_t len)
Definition AudioStreams.h:1992
void setOutput(AudioOutput &out)
Defines/Changes the output target and registers for audio change notifications.
Definition AudioStreams.h:1959
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioStreams.h:1862
Vector< float > volumes
Definition AudioStreams.h:1976
float f_volume_tmp
Definition AudioStreams.h:1974
size_t write(const uint8_t *data, size_t len) override
Definition AudioStreams.h:1853
Stream * p_stream
Definition AudioStreams.h:1981
unsigned long inactive_start_time
Definition AudioStreams.h:1990
float volumePercent(int channel)
Volume of indicated channel in %: max amplitude is 100.
Definition AudioStreams.h:1915
float volumeAvg()
Average volume of all channels.
Definition AudioStreams.h:1918
float f_volume
Definition AudioStreams.h:1975
void updateVolumesT(const uint8_t *buffer, size_t size)
Definition AudioStreams.h:2015
bool activity_monitoring_enabled
Definition AudioStreams.h:1988
Print * p_out
Definition AudioStreams.h:1980
Vector< float > sum_tmp
Definition AudioStreams.h:1979
VolumeMeter(Stream &stream)
Definition AudioStreams.h:1829
void updateVolume(float tmp, int j)
Definition AudioStreams.h:2026
void setActivityCallback(ActivityCallback callback, float threshold=0.2, unsigned long duration_ms=2000)
Definition AudioStreams.h:1946
void updateActivityState()
Definition AudioStreams.h:2048
void clear()
Resets the actual volume.
Definition AudioStreams.h:1934
bool begin() override
Definition AudioStreams.h:1836
float volumeRatio(int channel)
Volume Ratio of indicated channel: max amplitude is 1.0.
Definition AudioStreams.h:1893
float activity_threshold
Definition AudioStreams.h:1986
float volumeDB(int channel)
Volume of indicated channel in db: max amplitude is 0.
Definition AudioStreams.h:1905
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition AudioStreams.h:1841
void commit()
Definition AudioStreams.h:2039
ActivityCallback activity_callback
Definition AudioStreams.h:1985
void setStream(Stream &io) override
Defines/Changes the input & output.
Definition AudioStreams.h:1968
float volumeDB()
Volume in db: max amplitude is 0 (range: -1000 to 0)
Definition AudioStreams.h:1898
VolumeMeter(Print &print)
Definition AudioStreams.h:1828
bool begin(AudioInfo info)
Definition AudioStreams.h:1831
float volume(int channel)
Definition AudioStreams.h:1875
VolumeMeter(AudioStream &as)
Definition AudioStreams.h:1826
#define URL_CLIENT_TIMEOUT
Definition esp8266.h:23
MemoryType
Memory types.
Definition AudioTypes.h:37
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:30
@ RAM
Definition AudioTypes.h:37
@ PS_RAM
Definition AudioTypes.h:37
@ FLASH_RAM
Definition AudioTypes.h:37
@ RX_MODE
Definition AudioTypes.h:30
@ US
Definition AudioTypes.h:48
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:470
void delayMicroseconds(unsigned int us)
Definition Time.h:28
void delay(unsigned long ms)
Definition Time.h:23
static void timerCallback(void *obj)
Definition AudioStreams.h:2443
unsigned long micros(void)
Definition Time.h:33
void(*)(bool isActive) ActivityCallback
Callback function type for activity state changes.
Definition AudioStreams.h:1812
uint32_t millis()
Returns the milliseconds since the start.
Definition Time.h:12
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:512
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:55
void copyFrom(AudioInfo info)
Same as set.
Definition AudioTypes.h:105
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:57
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:59
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:61
virtual void clear()
Definition AudioTypes.h:119
Definition AudioStreams.h:1546
int channels
Definition AudioStreams.h:1548
MergeRecord(Stream *str, int ch, float w)
Definition AudioStreams.h:1551
float weight
Definition AudioStreams.h:1549
Stream * stream
Definition AudioStreams.h:1547
Configure Throttle setting.
Definition AudioStreams.h:1112
ThrottleConfig()
Definition AudioStreams.h:1113
int correction_us
Definition AudioStreams.h:1118
TimerCallbackAudioStream Configuration.
Definition AudioStreams.h:2263
TimerFunction timer_function
Definition AudioStreams.h:2268
RxTxMode rx_tx_mode
Definition AudioStreams.h:2264
uint16_t(* callback)(uint8_t *data, uint16_t len)
Definition AudioStreams.h:2270
bool use_timer
Definition AudioStreams.h:2266
int timer_id
Definition AudioStreams.h:2267
bool adapt_sample_rate
Definition AudioStreams.h:2269
uint16_t buffer_size
Definition AudioStreams.h:2265