arduino-audio-tools
Loading...
Searching...
No Matches
AudioIO.h
Go to the documentation of this file.
1#pragma once
5
6#ifndef MAX_ZERO_READ_COUNT
7#define MAX_ZERO_READ_COUNT 3
8#endif
9
10#ifndef CHANNEL_SELECT_BUFFER_SIZE
11#define CHANNEL_SELECT_BUFFER_SIZE 256
12#endif
13
14namespace audio_tools {
22template <class T>
24 public:
29 void begin(T* transform, Stream* source) {
30 TRACED();
31 active = true;
32 is_eof = false;
35 p_stream = source;
36 p_transform = transform;
37 if (transform == nullptr) {
38 LOGE("transform is NULL");
39 active = false;
40 }
41 if (p_stream == nullptr) {
42 LOGE("p_stream is NULL");
43 active = false;
44 }
45 }
46
47 size_t readBytes(uint8_t* data, size_t len) {
48 LOGD("TransformationReader::readBytes: %d", (int)len);
49 if (!active) {
50 LOGE("inactive");
51 return 0;
52 }
53 if (p_stream == nullptr) {
54 LOGE("p_stream is NULL");
55 return 0;
56 }
57
58 setupBuffers(len);
59
60 if (!is_eof) {
61 fillResultQueue(len);
62 }
63
64 int result_len = min((int)len, result_queue.available());
65 result_len = result_queue.readBytes(data, result_len);
66 LOGD("TransformationReader::readBytes: %d -> %d", (int)len, result_len);
67 total_bytes_read += result_len;
68 return result_len;
69 }
70
73 int available() {
74 if (!active || p_stream == nullptr || p_transform == nullptr) return 0;
75 if (is_eof) return result_queue.available();
78 int available_bytes = result_queue.available();
79 LOGD("TransformationReader::available: %d", available_bytes);
80 return available_bytes > max_read_size ? max_read_size : available_bytes;
81 }
82
83 void end() {
85 buffer.resize(0);
87 active = false;
88 }
89
91 void setResultQueueFactor(int factor) { result_queue_factor = factor; }
92
94 void resizeResultQueue(int size) {
97 }
98
99 void setMaxReadSize(int size) { max_read_size = size; }
100
101 size_t getTotalBytesRead() const { return total_bytes_read; }
102
111 void setEofOnZeroReads(bool flag) { eof_on_zero_reads = flag; }
112
122 void setZeroReadDelay(uint32_t delay_ms) { zero_read_delay_ms = delay_ms; }
123
124 protected:
127 Stream* p_stream = nullptr;
128 Vector<uint8_t> buffer{0}; // we allocate memory only when needed
129 T* p_transform = nullptr;
130 bool active = false;
134 float last_byte_factor = 0.0f;
135 bool is_eof = false;
136 bool eof_on_zero_reads = true;
137 uint32_t zero_read_delay_ms = 5;
139
141 void resizeReadBuffer(int size) { buffer.resize(size); }
142
143 void setupBuffers(size_t len) {
144 float byte_factor = p_transform->getByteFactor();
145 if (byte_factor <= 0.0f) {
146 LOGE("Invalid byte factor: %f", byte_factor);
147 byte_factor = 1.0f;
148 }
149 // Recompute if the requested length changed, or if the transform's byte
150 // factor drifted meaningfully since the read chunk size was last sized
151 // (e.g. a live-adjusted resampling step size). For a transform with a
152 // constant byte factor (the common decoder/encoder case) this check
153 // never re-triggers after the first call, so behavior there is
154 // unchanged; it only matters for transforms whose byte factor changes
155 // at runtime, where a stale chunk size would otherwise silently distort
156 // the consumption/production ratio.
157 bool byte_factor_changed =
158 fabsf(byte_factor - last_byte_factor) > 0.01f * last_byte_factor;
159 if (len == last_setup_buffer_size && !byte_factor_changed) return;
160 LOGD("setupBuffers: %d", (int)len);
161 last_byte_factor = byte_factor;
162
163 // we read half the necessary bytes
164 int size = (0.5f / byte_factor * len);
165 // process full samples/frames
166 size = size / 4 * 4;
167 if (size <= 0) size = 4;
168 if (buffer.size() < size) {
169 LOGI("read size: %d", size);
170 buffer.resize(size);
171 }
172
173 if (result_queue_buffer.size() == 0) {
174 // make sure that the ring buffer is big enough
175 int rb_size = len * result_queue_factor;
176 LOGI("buffer size: %d", rb_size);
179 }
181 }
182
185 void fillResultQueue(size_t len) {
186 if (is_eof) return;
187 if (result_queue.available() >= len) return;
188 LOGD("fillResultQueue: %d", (int)len);
189
190 // Detect misconfigured buffer: if the ring buffer capacity is smaller than
191 // the requested len bytes we can never satisfy the condition and will loop
192 // forever. Issue an error and bail out early.
193 if ((int)len > result_queue_buffer.size()) {
194 LOGE("fillResultQueue: result_queue_buffer too small: %d < %d. "
195 "Increase result_queue_factor or call resizeReadResultQueue().",
196 result_queue_buffer.size(), (int)len);
197 return;
198 }
199
200 Print* tmp = setupOutput();
201 int zero_count = 0;
202 while (result_queue.available() < len) {
203 // Detect buffer-full stall: if we can't write any more data but the
204 // queue is still below len, we must stop to avoid an endless loop.
206 LOGE("fillResultQueue: result_queue full (%d) but target not reached "
207 "(%d/%d). Increase result_queue_factor or call "
208 "resizeReadResultQueue().",
210 break;
211 }
212 int read_size = buffer.size();
213 int read_eff = p_stream->readBytes(buffer.data(), read_size);
214 LOGD("readBytes from source: %d -> %d", read_size,read_eff);
215 if (read_eff > 0) {
216 zero_count = 0; // reset 0 count
217 if (read_eff != buffer.size()) {
218 LOGD("readBytes %d -> %d", buffer.size(), read_eff);
219 }
220 int write_eff = p_transform->write(buffer.data(), read_eff);
221 if (write_eff != read_eff) {
222 LOGE("TransformationReader::write %d -> %d", read_eff, write_eff);
223 }
224 } else {
225 // limit the number of reads which provide 0;
226 if (++zero_count > MAX_ZERO_READ_COUNT) {
227 if (eof_on_zero_reads) {
228 is_eof = true;
229 // Flush any buffered/final encoder bytes into result_queue.
230 p_transform->flush();
231 }
232 // Otherwise the source is just a momentarily empty live
233 // producer (buffer underflow, not end of stream): stop trying
234 // for this call, but leave is_eof false so the next call
235 // retries once more data has arrived.
236 break;
237 }
238 // wait for some more data
240 }
241 }
242 LOGD("fillResultQueue available: %d", result_queue.available());
243 restoreOutput(tmp);
244 }
245
250 Print* result = p_transform->getPrint();
251 p_transform->setOutput((Print&)result_queue);
252
253 return result;
254 }
257 void restoreOutput(Print* out) {
258 if (out) p_transform->setOutput(*out);
259 }
260};
261
269 public:
270 virtual void setStream(Stream& stream) override {
271 TRACED();
272 p_stream = &stream;
273 p_print = &stream;
274 }
275
276 virtual void setStream(AudioStream& stream) {
277 TRACED();
278 p_stream = &stream;
279 p_print = &stream;
280 // setNotifyOnOutput(stream);
281 addNotifyAudioChange(stream);
282 }
283
284 virtual void setOutput(AudioOutput& print) {
285 TRACED();
286 p_print = &print;
288 }
289
290 virtual void setOutput(Print& print) override {
291 TRACED();
292 p_print = &print;
293 }
294
295 virtual Print* getPrint() { return p_print; }
296
297 virtual Stream* getStream() { return p_stream; }
298
299 size_t readBytes(uint8_t* data, size_t len) override {
300 LOGD("ReformatBaseStream::readBytes: %d", (int)len);
301 return reader.readBytes(data, len);
302 }
303
304 int available() override {
305 return reader.available();
306 }
307
308 int availableForWrite() override {
309 return DEFAULT_BUFFER_SIZE; // reader.availableForWrite();
310 }
311
312 virtual float getByteFactor() = 0;
313
319 virtual void flush() {}
320
321 void end() override {
322 TRACED();
324 reader.end();
325 }
326
329 void resizeReadResultQueue(int size) { reader.resizeResultQueue(size); }
330
332 void setReadResultQueueSize(int size) { reader.resizeResultQueue(size); }
333
335 void setMaxReadSize(int size) { reader.setMaxReadSize(size); }
336
341
342
343 protected:
345 Stream* p_stream = nullptr;
346 Print* p_print = nullptr;
347
348 void setupReader() {
349 if (getStream() != nullptr) {
350 reader.begin(this, getStream());
351 }
352 }
353};
354
360
366 public:
369 void setStream(Print& out) { p_print = &out; }
370 void setAudioInfo(AudioInfo info) { cfg = info; }
371 size_t write(const uint8_t* data, size_t len) {
372 return p_print->write(data, len);
373 }
375 virtual bool isDeletable() { return true; }
376
377 AudioInfo audioInfo() { return cfg; }
378
379 protected:
380 Print* p_print = nullptr;
382};
383
389 public:
391
393
394 void setStream(AudioStream& stream) { p_stream = &stream; }
395
396 void setAudioInfo(AudioInfo info) override { p_stream->setAudioInfo(info); }
397
398 AudioInfo audioInfo() override { return p_stream->audioInfo(); }
399
400 size_t write(const uint8_t* data, size_t len) override {
401 return p_stream->write(data, len);
402 }
403
404 int availableForWrite() override { return p_stream->availableForWrite(); }
405
406 bool begin() override { return p_stream->begin(); }
407
408 void end() override { p_stream->end(); }
409
411 virtual bool isDeletable() override { return true; }
412
413 operator bool() override { return *p_stream; }
414
415 protected:
417};
418
424 public:
426
428
429 void setOutput(AudioOutput& stream) { p_stream = &stream; }
430
432
433 AudioInfo audioInfo() override { return p_stream->audioInfo(); }
434
435 size_t write(const uint8_t* data, size_t len) override {
436 return p_stream->write(data, len);
437 }
438
439 bool begin() override { return p_stream->begin(); }
440
441 void end() override { p_stream->end(); }
442
444 virtual bool isDeletable() { return true; }
445
446 operator bool() override { return *p_stream; }
447
448 protected:
450};
451
459 public:
461 MultiOutput() = default;
462
463 MultiOutput(Print& out) { add(out); }
464
467
469
472 add(out1);
473 add(out2);
474 }
475
478 add(out1);
479 add(out2);
480 }
481
484 MultiOutput(Print& out1, Print& out2) {
485 add(out1);
486 add(out2);
487 }
488
489 virtual ~MultiOutput() { clear(); }
490
492 void add(AudioOutput& out) {
493 vector.push_back({&out, &out, Kind::AudioOutputKind});
494 }
495
497 void add(AudioStream& stream) {
498 vector.push_back({&stream, &stream, Kind::AudioStreamKind});
499 }
500
502 void add(Client& client) {
503 vector.push_back({&client, nullptr, Kind::ClientKind});
504 }
505
508 void add(Print& print) { vector.push_back({&print, nullptr, Kind::PrintKind}); }
509
511 void remove(Print& print) {
512 for (int j = 0; j < vector.size(); j++) {
513 if (vector[j].print == &print) {
514 vector.erase(j);
515 return;
516 }
517 }
518 }
519
520 void flush() {
521 for (int j = 0; j < vector.size(); j++) {
522 vector[j].print->flush();
523 }
524 }
525
527 for (int j = 0; j < vector.size(); j++) {
528 if (vector[j].info != nullptr) {
529 vector[j].info->setAudioInfo(info);
530 }
531 }
532 }
533
534 size_t write(const uint8_t* data, size_t len) override {
535 for (auto& rec : vector) {
536 int open = len;
537 int start = 0;
538 // create copy of data to avoid that one output changes the data for the
539 // other outputs
540 uint8_t copy[len];
541 memcpy(copy, data, len);
542 while (open > 0) {
543 int written = rec.print->write(copy + start, open);
544 open -= written;
545 start += written;
546 }
547 }
548 return len;
549 }
550
551 size_t write(uint8_t ch) override {
552 for (int j = 0; j < vector.size(); j++) {
553 int open = 1;
554 while (open > 0) {
555 open -= vector[j].print->write(ch);
556 }
557 }
558 return 1;
559 }
560
564 void clear() { vector.clear(); }
565
571 for (int j = vector.size() - 1; j >= 0; j--) {
572 if (!isActive(vector[j])) {
573 vector.erase(j);
574 }
575 }
576 }
577
578 protected:
582
597
599
604 switch (rec.kind) {
605 case Kind::ClientKind:
606 return (bool)*static_cast<Client*>(rec.print);
608 return (bool)*static_cast<AudioStream*>(rec.print);
610 return (bool)*static_cast<AudioOutput*>(rec.print);
611 default:
612 return true;
613 }
614 }
615
617 void setOutput(Print& out) { add(out); }
618};
619
630 public:
631 TimedStream() = default;
632
633 TimedStream(AudioStream& io, long startSeconds = 0, long endSeconds = -1) {
634 p_stream = &io;
635 p_print = &io;
636 p_info = &io;
637 setStartSec(startSeconds);
638 setEndSec(endSeconds);
639 }
640
641 TimedStream(AudioOutput& o, long startSeconds = 0, long endSeconds = -1) {
642 p_print = &o;
643 p_info = &o;
644 setStartSec(startSeconds);
645 setEndSec(endSeconds);
646 }
647
648 TimedStream(Stream& io, long startSeconds = 0, long endSeconds = -1) {
649 p_stream = &io;
650 p_print = &io;
651 setStartSec(startSeconds);
652 setEndSec(endSeconds);
653 }
654
655 TimedStream(Print& o, long startSeconds = 0, long endSeconds = -1) {
656 p_print = &o;
657 setStartSec(startSeconds);
658 setEndSec(endSeconds);
659 }
660
663 void setStartSec(uint32_t startSeconds) {
664 start_ms = startSeconds * 1000;
666 }
667
669 void setStartMs(uint32_t ms) {
670 start_ms = ms;
672 }
673
676 void setEndSec(uint32_t endSeconds) {
677 end_ms = endSeconds * 1000;
679 }
680
682 void setEndMs(uint32_t ms) {
683 end_ms = ms;
685 }
686
688 bool isPlaying() {
689 if (current_bytes < start_bytes) return false;
690 if (end_bytes > 0 && current_bytes > end_bytes) return false;
691 return true;
692 }
693
695 bool isActive() {
696 return (current_bytes < end_bytes && current_bytes >= start_bytes);
697 }
698
701 return begin();
702 }
703
704 bool begin() override {
706 current_bytes = 0;
707 LOGI("byte range %u - %u", (unsigned)start_bytes, (unsigned)end_bytes);
708 return true;
709 }
710
711 operator bool() override { return isActive(); }
712
716 size_t readBytes(uint8_t* data, size_t len) override {
717 // if reading is not supported we stop
718 if (p_stream == nullptr) return 0;
719 // Positioin to start
722 }
723 // if we are past the end we stop
724 if (!isActive()) return 0;
725 // read the data now
726 size_t result = 0;
727 do {
728 result = p_stream->readBytes(data, len);
729 current_bytes += len;
730 // ignore data before start time
731 } while (result > 0 && current_bytes < start_bytes);
732 return isPlaying() ? result : 0;
733 }
734
736 size_t write(const uint8_t* data, size_t len) override {
737 if (current_bytes >= end_bytes) return 0;
738 current_bytes += len;
739 if (current_bytes < start_bytes) return len;
740 return p_print->write(data, len);
741 }
742
744 int available() override {
745 if (p_stream == nullptr) return 0;
746 return current_bytes < end_bytes ? p_stream->available() : 0;
747 }
748
755
756 int availableForWrite() override {
758 }
759
762 void setCompressionRatio(float ratio) { compression_ratio = ratio; }
763
768
769 void setOutput(Print& out) override { p_print = &out; }
770
771 void setStream(Stream& stream) override {
772 p_print = &stream;
773 p_stream = &stream;
774 }
775
777 p_print = &out;
778 p_info = &out;
779 }
780
782 p_print = &out;
783 p_info = &out;
784 }
785
786 void setStream(AudioStream& stream) {
787 p_print = &stream;
788 p_stream = &stream;
789 p_info = &stream;
790 }
791
792 size_t size() { return end_bytes - start_bytes; }
793
794 protected:
795 Stream* p_stream = nullptr;
796 Print* p_print = nullptr;
798 uint32_t start_ms = 0;
799 uint32_t end_ms = UINT32_MAX;
800 uint32_t start_bytes = 0;
801 uint32_t end_bytes = UINT32_MAX;
802 uint32_t current_bytes = 0;
803 float compression_ratio = 1.0;
804
805 void consumeBytes(uint32_t len) {
806 int open = len;
807 uint8_t buffer[1024];
808 while (open > 0) {
809 int toread = min(1024, open);
810 p_stream->readBytes(buffer, toread);
811 open -= toread;
812 }
813 current_bytes += len;
814 LOGD("consumed %u -> %u", (unsigned)len, (unsigned)current_bytes);
815 }
816
818 float bytes_per_second = bytesPerSecond();
819 if (bytes_per_second > 0) {
820 start_bytes = bytes_per_second * start_ms / compression_ratio / 1000;
821 end_bytes = bytes_per_second * end_ms / compression_ratio / 1000;
822 } else {
823 LOGE("AudioInfo not defined");
824 }
825 }
826};
827
838 public:
840
841 bool begin(AudioInfo info) override {
842 setAudioInfo(info);
843 return begin();
844 }
845
846 bool begin() override {
848 // make sure that selected channels are valid
849 for (auto& out : out_channels) {
850 for (auto& ch : out.channels) {
851 if (ch > cfg.channels - 1) {
852 LOGE("Channel '%d' not valid for max %d channels", ch, cfg.channels);
853 return false;
854 }
855 }
856 }
857 return true;
858 }
859
862 void addOutput(AudioOutput& out, uint16_t channel) {
863 Vector<uint16_t> channels;
864 channels.push_back(channel);
866 def.channels = channels;
867 def.p_out = &out;
868 def.p_audio_info = &out;
869 out_channels.push_back(def);
870 }
871
874 void addOutput(AudioStream& out, uint16_t channel) {
875 Vector<uint16_t> channels;
876 channels.push_back(channel);
878 def.channels = channels;
879 def.p_out = &out;
880 def.p_audio_info = &out;
881 out_channels.push_back(def);
882 }
883
886 void addOutput(Print& out, uint16_t channel) {
887 Vector<uint16_t> channels;
888 channels.push_back(channel);
890 def.channels = channels;
891 def.p_out = &out;
892 out_channels.push_back(def);
893 }
894
897 void addOutput(Print& out, uint16_t left, uint16_t right) {
898 Vector<uint16_t> channels;
899 channels.push_back(left);
900 channels.push_back(right);
902 def.channels = channels;
903 def.p_out = &out;
904 out_channels.push_back(def);
905 }
906
909 void addOutput(AudioOutput& out, uint16_t left, uint16_t right) {
910 Vector<uint16_t> channels;
911 channels.push_back(left);
912 channels.push_back(right);
914 def.channels = channels;
915 def.p_out = &out;
916 def.p_audio_info = &out;
917 out_channels.push_back(def);
918 }
919
922 void addOutput(AudioStream& out, uint16_t left, uint16_t right) {
923 Vector<uint16_t> channels;
924 channels.push_back(left);
925 channels.push_back(right);
927 def.channels = channels;
928 def.p_out = &out;
929 def.p_audio_info = &out;
930 out_channels.push_back(def);
931 }
932
933 size_t write(const uint8_t* data, size_t len) override {
934 if (!is_active) return false;
935 LOGD("write %d", (int)len);
936 switch (cfg.bits_per_sample) {
937 case 16:
938 return writeT<int16_t>(data, len);
939 case 24:
940 return writeT<int24_t>(data, len);
941 case 32:
942 return writeT<int32_t>(data, len);
943 default:
944 return 0;
945 }
946 }
947
948 void setAudioInfo(AudioInfo ai) override {
949 this->cfg = ai;
950 // notifyAudioChange(ai);
951 for (auto& info : out_channels) {
952 auto p_notify = info.p_audio_info;
953 if (p_notify != nullptr) {
954 AudioInfo result{ai};
955 result.channels = info.channels.size();
956 p_notify->setAudioInfo(result);
957 }
958 }
959 }
960
961 protected:
969
970 template <typename T>
971 size_t writeT(const uint8_t* buffer, size_t size) {
972 if (!is_active) return 0;
973 int sample_count = size / sizeof(T);
974 // int result_size = sample_count / cfg.channels;
975 T* data = (T*)buffer;
976
977 for (int i = 0; i < sample_count; i += cfg.channels) {
978 T* frame = data + i;
979 for (auto& out : out_channels) {
980 T out_frame[out.channels.size()];
981 int ch_out = 0;
982 for (auto& ch : out.channels) {
983 // make sure we have a valid channel
984 int channel = (ch < cfg.channels) ? ch : cfg.channels - 1;
985 out_frame[ch_out++] = frame[channel];
986 }
987 // write to buffer
988 size_t written = out.buffer.writeArray((const uint8_t*)&out_frame,
989 sizeof(out_frame));
990 // write buffer to final output
991 if (out.buffer.availableForWrite() < sizeof(out_frame)) {
992 out.p_out->write(out.buffer.data(), out.buffer.available());
993 out.buffer.reset();
994 }
995 // if (written != sizeof(out_frame)) {
996 // LOGW("Could not write all samples %d -> %d", sizeof(out_frame),
997 // written);
998 // }
999 }
1000 }
1001 return size;
1002 }
1003
1005 int getChannels(Print* out, int defaultChannels) {
1006 for (auto& channels_select : out_channels) {
1007 if (channels_select.p_out == out) return channels_select.channels.size();
1008 }
1009 return defaultChannels;
1010 }
1011};
1012
1013} // namespace audio_tools
#define CHANNEL_SELECT_BUFFER_SIZE
Definition AudioIO.h:11
#define MAX_ZERO_READ_COUNT
Definition AudioIO.h:7
#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 DEFAULT_BUFFER_SIZE
Definition avr.h:20
Definition Arduino.h:162
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
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
Wrapper which converts a AudioStream to a AudioOutput.
Definition AudioIO.h:423
void setOutput(AudioOutput &stream)
Definition AudioIO.h:429
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition AudioIO.h:444
AdapterAudioOutputToAudioStream(AudioOutput &stream)
Definition AudioIO.h:427
void end() override
Definition AudioIO.h:441
size_t write(const uint8_t *data, size_t len) override
Definition AudioIO.h:435
AudioOutput * p_stream
Definition AudioIO.h:449
bool begin() override
Definition AudioIO.h:439
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition AudioIO.h:431
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioIO.h:433
Wrapper which converts a AudioStream to a AudioOutput.
Definition AudioIO.h:388
void setStream(AudioStream &stream)
Definition AudioIO.h:394
virtual bool isDeletable() override
If true we need to release the related memory in the destructor.
Definition AudioIO.h:411
void end() override
Definition AudioIO.h:408
size_t write(const uint8_t *data, size_t len) override
Definition AudioIO.h:400
AdapterAudioStreamToAudioOutput(AudioStream &stream)
Definition AudioIO.h:392
int availableForWrite() override
Definition AudioIO.h:404
AudioStream * p_stream
Definition AudioIO.h:416
bool begin() override
Definition AudioIO.h:406
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition AudioIO.h:396
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioIO.h:398
Wrapper which converts a Print to a AudioOutput.
Definition AudioIO.h:365
AdapterPrintToAudioOutput(Print &print)
Definition AudioIO.h:368
AudioInfo cfg
Definition AudioIO.h:381
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition AudioIO.h:375
void setAudioInfo(AudioInfo info)
Defines the input AudioInfo.
Definition AudioIO.h:370
void setStream(Print &out)
Definition AudioIO.h:369
AudioInfo audioInfo()
provides the actual input AudioInfo
Definition AudioIO.h:377
Print * p_print
Definition AudioIO.h:380
size_t write(const uint8_t *data, size_t len)
Definition AudioIO.h:371
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 void setAudioInfo(AudioInfo info)=0
Defines the input AudioInfo.
Base class for Output Adpapters.
Definition AudioIO.h:359
Abstract Audio Ouptut class.
Definition AudioOutput.h:25
AudioInfo cfg
Definition AudioOutput.h:88
bool is_active
Definition AudioOutput.h:90
virtual bool begin(AudioInfo info)
Definition AudioOutput.h:73
virtual bool begin()
Definition AudioOutput.h:78
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition AudioOutput.h:49
virtual void end()
Definition AudioOutput.h:82
virtual size_t write(const uint8_t *data, size_t len) override=0
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioOutput.h:62
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:120
virtual size_t write(const uint8_t *data, size_t len) override
Definition BaseStream.h:146
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
virtual bool begin()
Definition BaseStream.h:40
virtual int availableForWrite() override
Definition BaseStream.h:57
virtual void end()
Definition BaseStream.h:41
Flexible functionality to extract one or more channels from a multichannel signal....
Definition AudioIO.h:837
void addOutput(Print &out, uint16_t left, uint16_t right)
Definition AudioIO.h:897
void setAudioInfo(AudioInfo ai) override
Defines the input AudioInfo.
Definition AudioIO.h:948
void addOutput(Print &out, uint16_t channel)
Definition AudioIO.h:886
Vector< ChannelSelectionOutputDef > out_channels
Definition AudioIO.h:968
void addOutput(AudioOutput &out, uint16_t channel)
Definition AudioIO.h:862
int getChannels(Print *out, int defaultChannels)
Determine number of channels for destination.
Definition AudioIO.h:1005
size_t write(const uint8_t *data, size_t len) override
Definition AudioIO.h:933
size_t writeT(const uint8_t *buffer, size_t size)
Definition AudioIO.h:971
bool begin(AudioInfo info) override
Definition AudioIO.h:841
bool begin() override
Definition AudioIO.h:846
void addOutput(AudioStream &out, uint16_t channel)
Definition AudioIO.h:874
void addOutput(AudioStream &out, uint16_t left, uint16_t right)
Definition AudioIO.h:922
void addOutput(AudioOutput &out, uint16_t left, uint16_t right)
Definition AudioIO.h:909
Abstract class: Objects can be put into a pipleline.
Definition AudioOutput.h:100
Abstract class: Objects can be put into a pipleline.
Definition AudioStreams.h:68
Replicates the output to multiple destinations.
Definition AudioIO.h:458
bool isActive(MultiOutputRecord &rec)
Definition AudioIO.h:603
void remove(Print &print)
Removes the indicated output.
Definition AudioIO.h:511
void add(AudioOutput &out)
Add an additional AudioOutput output.
Definition AudioIO.h:492
void clearInactive()
Definition AudioIO.h:570
MultiOutput(Print &out)
Definition AudioIO.h:463
Vector< MultiOutputRecord > vector
Definition AudioIO.h:598
size_t write(uint8_t ch) override
Definition AudioIO.h:551
void setAudioInfo(AudioInfo info)
Defines the input AudioInfo.
Definition AudioIO.h:526
void add(AudioStream &stream)
Add an AudioStream to the output.
Definition AudioIO.h:497
MultiOutput(AudioStream &out1, AudioStream &out2)
Defines a MultiOutput with 2 final outputs.
Definition AudioIO.h:477
size_t write(const uint8_t *data, size_t len) override
Definition AudioIO.h:534
void add(Print &print)
Definition AudioIO.h:508
void add(Client &client)
Add a (network) Client as output: e.g. WiFiClient, EthernetClient...
Definition AudioIO.h:502
MultiOutput(AudioOutput &out1, AudioOutput &out2)
Defines a MultiOutput with 2 final outputs.
Definition AudioIO.h:471
MultiOutput(AudioOutput &out)
Defines a MultiOutput with a single final outputs,.
Definition AudioIO.h:466
Kind
Definition AudioIO.h:581
MultiOutput(AudioStream &out)
Definition AudioIO.h:468
virtual ~MultiOutput()
Definition AudioIO.h:489
void clear()
Definition AudioIO.h:564
void flush()
Definition AudioIO.h:520
void setOutput(Print &out)
support for Pipleline
Definition AudioIO.h:617
MultiOutput(Print &out1, Print &out2)
Definition AudioIO.h:484
MultiOutput()=default
Defines a MultiOutput with no final output: Define your outputs with add()
Stream class which stores the data in a temporary queue buffer. The queue can be consumed e....
Definition BaseStream.h:359
virtual bool begin() override
Activates the output.
Definition BaseStream.h:387
virtual size_t readBytes(uint8_t *data, size_t len) override
Definition BaseStream.h:445
int available() override
Definition BaseStream.h:411
Base class for chained converting streams.
Definition AudioIO.h:268
void setMaxReadSize(int size)
Defines the read buffer size for individual reads: same as transformationReader()....
Definition AudioIO.h:335
virtual void setStream(AudioStream &stream)
Defines/Changes the input & output and registers for audio change notifications.
Definition AudioIO.h:276
virtual void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioIO.h:270
TransformationReader< ReformatBaseStream > reader
Definition AudioIO.h:344
virtual float getByteFactor()=0
virtual void setOutput(Print &print) override
Defines/Changes the output target.
Definition AudioIO.h:290
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioIO.h:299
void end() override
Definition AudioIO.h:321
int available() override
Definition AudioIO.h:304
virtual Stream * getStream()
Definition AudioIO.h:297
virtual void setOutput(AudioOutput &print)
Defines/Changes the output target and registers for audio change notifications.
Definition AudioIO.h:284
Stream * p_stream
Definition AudioIO.h:345
virtual TransformationReader< ReformatBaseStream > & transformationReader()
Provides access to the TransformationReader.
Definition AudioIO.h:338
int availableForWrite() override
Definition AudioIO.h:308
void setReadResultQueueSize(int size)
same as resizeReadResultQueue(size)
Definition AudioIO.h:332
virtual Print * getPrint()
Definition AudioIO.h:295
Print * p_print
Definition AudioIO.h:346
virtual void flush()
Definition AudioIO.h:319
void setupReader()
Definition AudioIO.h:348
void resizeReadResultQueue(int size)
Definition AudioIO.h:329
Implements a typed Ringbuffer.
Definition Buffers.h:358
virtual size_t size() override
Returns the maximum capacity of the buffer.
Definition Buffers.h:488
virtual bool resize(size_t len)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:478
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition Buffers.h:189
AudioStream class that can define a start and (an optional) stop time Usually it is used to wrap an A...
Definition AudioIO.h:629
TimedStream(Print &o, long startSeconds=0, long endSeconds=-1)
Definition AudioIO.h:655
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioIO.h:769
size_t size()
Definition AudioIO.h:792
void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioIO.h:771
uint32_t end_ms
Definition AudioIO.h:799
void setEndSec(uint32_t endSeconds)
Definition AudioIO.h:676
uint32_t start_bytes
Definition AudioIO.h:800
void setEndMs(uint32_t ms)
Defines the (optional) end time in milliseconds.
Definition AudioIO.h:682
uint32_t current_bytes
Definition AudioIO.h:802
void setStream(AudioOutput &out)
Definition AudioIO.h:781
void setCompressionRatio(float ratio)
Definition AudioIO.h:762
uint32_t start_ms
Definition AudioIO.h:798
void setOutput(AudioOutput &out)
Defines/Changes the output target and registers for audio change notifications.
Definition AudioIO.h:776
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioIO.h:716
void setStartSec(uint32_t startSeconds)
Definition AudioIO.h:663
TimedStream(Stream &io, long startSeconds=0, long endSeconds=-1)
Definition AudioIO.h:648
void setStream(AudioStream &stream)
Defines/Changes the input & output and registers for audio change notifications.
Definition AudioIO.h:786
TimedStream(AudioStream &io, long startSeconds=0, long endSeconds=-1)
Definition AudioIO.h:633
void consumeBytes(uint32_t len)
Definition AudioIO.h:805
int available() override
Provides the available bytes until the end time has reached.
Definition AudioIO.h:744
size_t write(const uint8_t *data, size_t len) override
Plays only data for the indiated start and end time.
Definition AudioIO.h:736
Stream * p_stream
Definition AudioIO.h:795
void setStartMs(uint32_t ms)
Defines the start time in milliseconds.
Definition AudioIO.h:669
bool isPlaying()
Returns true if we are in a valid time range and are still playing sound.
Definition AudioIO.h:688
int availableForWrite() override
Definition AudioIO.h:756
AudioInfoSupport * p_info
Definition AudioIO.h:797
bool isActive()
Returns true if we are not past the end time;.
Definition AudioIO.h:695
void calculateByteLimits()
Definition AudioIO.h:817
bool begin() override
Definition AudioIO.h:704
Print * p_print
Definition AudioIO.h:796
uint32_t end_bytes
Definition AudioIO.h:801
TimedStream(AudioOutput &o, long startSeconds=0, long endSeconds=-1)
Definition AudioIO.h:641
void setAudioInfo(AudioInfo info) override
Updates the AudioInfo in the current object and in the source or target.
Definition AudioIO.h:750
float compression_ratio
Definition AudioIO.h:803
bool begin(AudioInfo info)
Definition AudioIO.h:699
int bytesPerSecond()
Calculates the bytes per second from the AudioInfo.
Definition AudioIO.h:765
ConverterStream Helper class which implements the readBytes with the help of write.
Definition AudioIO.h:23
bool active
Definition AudioIO.h:130
QueueStream< uint8_t > result_queue
Definition AudioIO.h:126
void setupBuffers(size_t len)
Definition AudioIO.h:143
void setMaxReadSize(int size)
Definition AudioIO.h:99
void begin(T *transform, Stream *source)
setup of the TransformationReader class
Definition AudioIO.h:29
void resizeReadBuffer(int size)
Defines the read buffer size for individual reads.
Definition AudioIO.h:141
int last_setup_buffer_size
Definition AudioIO.h:133
float last_byte_factor
Definition AudioIO.h:134
void setEofOnZeroReads(bool flag)
Definition AudioIO.h:111
RingBuffer< uint8_t > result_queue_buffer
Definition AudioIO.h:125
T * p_transform
Definition AudioIO.h:129
int available()
Definition AudioIO.h:73
void restoreOutput(Print *out)
restores the original output in the converter class
Definition AudioIO.h:257
bool is_eof
Definition AudioIO.h:135
size_t total_bytes_read
Definition AudioIO.h:138
Stream * p_stream
Definition AudioIO.h:127
void fillResultQueue(size_t len)
Definition AudioIO.h:185
size_t readBytes(uint8_t *data, size_t len)
Definition AudioIO.h:47
Print * setupOutput()
Definition AudioIO.h:249
size_t getTotalBytesRead() const
Definition AudioIO.h:101
void end()
Definition AudioIO.h:83
uint32_t zero_read_delay_ms
Definition AudioIO.h:137
bool eof_on_zero_reads
Definition AudioIO.h:136
int max_read_size
Definition AudioIO.h:132
void setZeroReadDelay(uint32_t delay_ms)
Definition AudioIO.h:122
void resizeResultQueue(int size)
Defines the queue size for result.
Definition AudioIO.h:94
void setResultQueueFactor(int factor)
Defines the queue size dependent on the read size.
Definition AudioIO.h:91
int result_queue_factor
Definition AudioIO.h:131
Vector< uint8_t > buffer
Definition AudioIO.h:128
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
void push_back(T &&value)
Definition Vector.h:182
bool resize(size_t newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
int size()
Definition Vector.h:178
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
void delay(uint32_t ms)
Definition Arduino.h:259
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
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
AudioInfoSupport * p_audio_info
Definition AudioIO.h:964
Vector< uint16_t > channels
Definition AudioIO.h:966
SingleBuffer< uint8_t > buffer
Definition AudioIO.h:965
Record describing a single replicated output.
Definition AudioIO.h:584
Print * print
Target to which the data is actually written.
Definition AudioIO.h:586
AudioInfoSupport * info
Definition AudioIO.h:589
MultiOutputRecord(Print *print=nullptr, AudioInfoSupport *info=nullptr, Kind kind=Kind::PrintKind)
Definition AudioIO.h:593
Kind kind
Actual type of the object behind print.
Definition AudioIO.h:591