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
113 protected:
116 Stream* p_stream = nullptr;
117 Vector<uint8_t> buffer{0}; // we allocate memory only when needed
118 T* p_transform = nullptr;
119 bool active = false;
123 float last_byte_factor = 0.0f;
124 bool is_eof = false;
125 bool eof_on_zero_reads = true;
127
129 void resizeReadBuffer(int size) { buffer.resize(size); }
130
131 void setupBuffers(size_t len) {
132 float byte_factor = p_transform->getByteFactor();
133 if (byte_factor <= 0.0f) {
134 LOGE("Invalid byte factor: %f", byte_factor);
135 byte_factor = 1.0f;
136 }
137 // Recompute if the requested length changed, or if the transform's byte
138 // factor drifted meaningfully since the read chunk size was last sized
139 // (e.g. a live-adjusted resampling step size). For a transform with a
140 // constant byte factor (the common decoder/encoder case) this check
141 // never re-triggers after the first call, so behavior there is
142 // unchanged; it only matters for transforms whose byte factor changes
143 // at runtime, where a stale chunk size would otherwise silently distort
144 // the consumption/production ratio.
145 bool byte_factor_changed =
146 fabsf(byte_factor - last_byte_factor) > 0.01f * last_byte_factor;
147 if (len == last_setup_buffer_size && !byte_factor_changed) return;
148 LOGD("setupBuffers: %d", (int)len);
149 last_byte_factor = byte_factor;
150
151 // we read half the necessary bytes
152 int size = (0.5f / byte_factor * len);
153 // process full samples/frames
154 size = size / 4 * 4;
155 if (size <= 0) size = 4;
156 if (buffer.size() < size) {
157 LOGI("read size: %d", size);
158 buffer.resize(size);
159 }
160
161 if (result_queue_buffer.size() == 0) {
162 // make sure that the ring buffer is big enough
163 int rb_size = len * result_queue_factor;
164 LOGI("buffer size: %d", rb_size);
167 }
169 }
170
173 void fillResultQueue(size_t len) {
174 if (is_eof) return;
175 if (result_queue.available() >= len) return;
176 LOGD("fillResultQueue: %d", (int)len);
177
178 // Detect misconfigured buffer: if the ring buffer capacity is smaller than
179 // the requested len bytes we can never satisfy the condition and will loop
180 // forever. Issue an error and bail out early.
181 if ((int)len > result_queue_buffer.size()) {
182 LOGE("fillResultQueue: result_queue_buffer too small: %d < %d. "
183 "Increase result_queue_factor or call resizeReadResultQueue().",
184 result_queue_buffer.size(), (int)len);
185 return;
186 }
187
188 Print* tmp = setupOutput();
189 int zero_count = 0;
190 while (result_queue.available() < len) {
191 // Detect buffer-full stall: if we can't write any more data but the
192 // queue is still below len, we must stop to avoid an endless loop.
194 LOGE("fillResultQueue: result_queue full (%d) but target not reached "
195 "(%d/%d). Increase result_queue_factor or call "
196 "resizeReadResultQueue().",
198 break;
199 }
200 int read_size = buffer.size();
201 int read_eff = p_stream->readBytes(buffer.data(), read_size);
202 LOGD("readBytes from source: %d -> %d", read_size,read_eff);
203 if (read_eff > 0) {
204 zero_count = 0; // reset 0 count
205 if (read_eff != buffer.size()) {
206 LOGD("readBytes %d -> %d", buffer.size(), read_eff);
207 }
208 int write_eff = p_transform->write(buffer.data(), read_eff);
209 if (write_eff != read_eff) {
210 LOGE("TransformationReader::write %d -> %d", read_eff, write_eff);
211 }
212 } else {
213 // limit the number of reads which provide 0;
214 if (++zero_count > MAX_ZERO_READ_COUNT) {
215 if (eof_on_zero_reads) {
216 is_eof = true;
217 // Flush any buffered/final encoder bytes into result_queue.
218 p_transform->flush();
219 }
220 // Otherwise the source is just a momentarily empty live
221 // producer (buffer underflow, not end of stream): stop trying
222 // for this call, but leave is_eof false so the next call
223 // retries once more data has arrived.
224 break;
225 }
226 // wait for some more data
227 delay(5);
228 }
229 }
230 LOGD("fillResultQueue available: %d", result_queue.available());
231 restoreOutput(tmp);
232 }
233
238 Print* result = p_transform->getPrint();
239 p_transform->setOutput((Print&)result_queue);
240
241 return result;
242 }
245 void restoreOutput(Print* out) {
246 if (out) p_transform->setOutput(*out);
247 }
248};
249
257 public:
258 virtual void setStream(Stream& stream) override {
259 TRACED();
260 p_stream = &stream;
261 p_print = &stream;
262 }
263
264 virtual void setStream(AudioStream& stream) {
265 TRACED();
266 p_stream = &stream;
267 p_print = &stream;
268 // setNotifyOnOutput(stream);
269 addNotifyAudioChange(stream);
270 }
271
272 virtual void setOutput(AudioOutput& print) {
273 TRACED();
274 p_print = &print;
276 }
277
278 virtual void setOutput(Print& print) override {
279 TRACED();
280 p_print = &print;
281 }
282
283 virtual Print* getPrint() { return p_print; }
284
285 virtual Stream* getStream() { return p_stream; }
286
287 size_t readBytes(uint8_t* data, size_t len) override {
288 LOGD("ReformatBaseStream::readBytes: %d", (int)len);
289 return reader.readBytes(data, len);
290 }
291
292 int available() override {
293 return reader.available();
294 }
295
296 int availableForWrite() override {
297 return DEFAULT_BUFFER_SIZE; // reader.availableForWrite();
298 }
299
300 virtual float getByteFactor() = 0;
301
307 virtual void flush() {}
308
309 void end() override {
310 TRACED();
312 reader.end();
313 }
314
317 void resizeReadResultQueue(int size) { reader.resizeResultQueue(size); }
318
320 void setReadResultQueueSize(int size) { reader.resizeResultQueue(size); }
321
323 void setMaxReadSize(int size) { reader.setMaxReadSize(size); }
324
329
330
331 protected:
333 Stream* p_stream = nullptr;
334 Print* p_print = nullptr;
335
336 void setupReader() {
337 if (getStream() != nullptr) {
338 reader.begin(this, getStream());
339 }
340 }
341};
342
348
354 public:
357 void setStream(Print& out) { p_print = &out; }
358 void setAudioInfo(AudioInfo info) { cfg = info; }
359 size_t write(const uint8_t* data, size_t len) {
360 return p_print->write(data, len);
361 }
363 virtual bool isDeletable() { return true; }
364
365 AudioInfo audioInfo() { return cfg; }
366
367 protected:
368 Print* p_print = nullptr;
370};
371
377 public:
379
381
382 void setStream(AudioStream& stream) { p_stream = &stream; }
383
384 void setAudioInfo(AudioInfo info) override { p_stream->setAudioInfo(info); }
385
386 AudioInfo audioInfo() override { return p_stream->audioInfo(); }
387
388 size_t write(const uint8_t* data, size_t len) override {
389 return p_stream->write(data, len);
390 }
391
392 int availableForWrite() override { return p_stream->availableForWrite(); }
393
394 bool begin() override { return p_stream->begin(); }
395
396 void end() override { p_stream->end(); }
397
399 virtual bool isDeletable() override { return true; }
400
401 operator bool() override { return *p_stream; }
402
403 protected:
405};
406
412 public:
414
416
417 void setOutput(AudioOutput& stream) { p_stream = &stream; }
418
420
421 AudioInfo audioInfo() override { return p_stream->audioInfo(); }
422
423 size_t write(const uint8_t* data, size_t len) override {
424 return p_stream->write(data, len);
425 }
426
427 bool begin() override { return p_stream->begin(); }
428
429 void end() override { p_stream->end(); }
430
432 virtual bool isDeletable() { return true; }
433
434 operator bool() override { return *p_stream; }
435
436 protected:
438};
439
447 public:
449 MultiOutput() = default;
450
451 MultiOutput(Print& out) { add(out); }
452
455
457
460 add(out1);
461 add(out2);
462 }
463
466 add(out1);
467 add(out2);
468 }
469
472 MultiOutput(Print& out1, Print& out2) {
473 add(out1);
474 add(out2);
475 }
476
477 virtual ~MultiOutput() { clear(); }
478
480 void add(AudioOutput& out) {
481 vector.push_back({&out, &out, Kind::AudioOutputKind});
482 }
483
485 void add(AudioStream& stream) {
486 vector.push_back({&stream, &stream, Kind::AudioStreamKind});
487 }
488
490 void add(Client& client) {
491 vector.push_back({&client, nullptr, Kind::ClientKind});
492 }
493
496 void add(Print& print) { vector.push_back({&print, nullptr, Kind::PrintKind}); }
497
499 void remove(Print& print) {
500 for (int j = 0; j < vector.size(); j++) {
501 if (vector[j].print == &print) {
502 vector.erase(j);
503 return;
504 }
505 }
506 }
507
508 void flush() {
509 for (int j = 0; j < vector.size(); j++) {
510 vector[j].print->flush();
511 }
512 }
513
515 for (int j = 0; j < vector.size(); j++) {
516 if (vector[j].info != nullptr) {
517 vector[j].info->setAudioInfo(info);
518 }
519 }
520 }
521
522 size_t write(const uint8_t* data, size_t len) override {
523 for (auto& rec : vector) {
524 int open = len;
525 int start = 0;
526 // create copy of data to avoid that one output changes the data for the
527 // other outputs
528 uint8_t copy[len];
529 memcpy(copy, data, len);
530 while (open > 0) {
531 int written = rec.print->write(copy + start, open);
532 open -= written;
533 start += written;
534 }
535 }
536 return len;
537 }
538
539 size_t write(uint8_t ch) override {
540 for (int j = 0; j < vector.size(); j++) {
541 int open = 1;
542 while (open > 0) {
543 open -= vector[j].print->write(ch);
544 }
545 }
546 return 1;
547 }
548
552 void clear() { vector.clear(); }
553
559 for (int j = vector.size() - 1; j >= 0; j--) {
560 if (!isActive(vector[j])) {
561 vector.erase(j);
562 }
563 }
564 }
565
566 protected:
570
585
587
592 switch (rec.kind) {
593 case Kind::ClientKind:
594 return (bool)*static_cast<Client*>(rec.print);
596 return (bool)*static_cast<AudioStream*>(rec.print);
598 return (bool)*static_cast<AudioOutput*>(rec.print);
599 default:
600 return true;
601 }
602 }
603
605 void setOutput(Print& out) { add(out); }
606};
607
618 public:
619 TimedStream() = default;
620
621 TimedStream(AudioStream& io, long startSeconds = 0, long endSeconds = -1) {
622 p_stream = &io;
623 p_print = &io;
624 p_info = &io;
625 setStartSec(startSeconds);
626 setEndSec(endSeconds);
627 }
628
629 TimedStream(AudioOutput& o, long startSeconds = 0, long endSeconds = -1) {
630 p_print = &o;
631 p_info = &o;
632 setStartSec(startSeconds);
633 setEndSec(endSeconds);
634 }
635
636 TimedStream(Stream& io, long startSeconds = 0, long endSeconds = -1) {
637 p_stream = &io;
638 p_print = &io;
639 setStartSec(startSeconds);
640 setEndSec(endSeconds);
641 }
642
643 TimedStream(Print& o, long startSeconds = 0, long endSeconds = -1) {
644 p_print = &o;
645 setStartSec(startSeconds);
646 setEndSec(endSeconds);
647 }
648
651 void setStartSec(uint32_t startSeconds) {
652 start_ms = startSeconds * 1000;
654 }
655
657 void setStartMs(uint32_t ms) {
658 start_ms = ms;
660 }
661
664 void setEndSec(uint32_t endSeconds) {
665 end_ms = endSeconds * 1000;
667 }
668
670 void setEndMs(uint32_t ms) {
671 end_ms = ms;
673 }
674
676 bool isPlaying() {
677 if (current_bytes < start_bytes) return false;
678 if (end_bytes > 0 && current_bytes > end_bytes) return false;
679 return true;
680 }
681
683 bool isActive() {
684 return (current_bytes < end_bytes && current_bytes >= start_bytes);
685 }
686
689 return begin();
690 }
691
692 bool begin() override {
694 current_bytes = 0;
695 LOGI("byte range %u - %u", (unsigned)start_bytes, (unsigned)end_bytes);
696 return true;
697 }
698
699 operator bool() override { return isActive(); }
700
704 size_t readBytes(uint8_t* data, size_t len) override {
705 // if reading is not supported we stop
706 if (p_stream == nullptr) return 0;
707 // Positioin to start
710 }
711 // if we are past the end we stop
712 if (!isActive()) return 0;
713 // read the data now
714 size_t result = 0;
715 do {
716 result = p_stream->readBytes(data, len);
717 current_bytes += len;
718 // ignore data before start time
719 } while (result > 0 && current_bytes < start_bytes);
720 return isPlaying() ? result : 0;
721 }
722
724 size_t write(const uint8_t* data, size_t len) override {
725 if (current_bytes >= end_bytes) return 0;
726 current_bytes += len;
727 if (current_bytes < start_bytes) return len;
728 return p_print->write(data, len);
729 }
730
732 int available() override {
733 if (p_stream == nullptr) return 0;
734 return current_bytes < end_bytes ? p_stream->available() : 0;
735 }
736
743
744 int availableForWrite() override {
746 }
747
750 void setCompressionRatio(float ratio) { compression_ratio = ratio; }
751
756
757 void setOutput(Print& out) override { p_print = &out; }
758
759 void setStream(Stream& stream) override {
760 p_print = &stream;
761 p_stream = &stream;
762 }
763
765 p_print = &out;
766 p_info = &out;
767 }
768
770 p_print = &out;
771 p_info = &out;
772 }
773
774 void setStream(AudioStream& stream) {
775 p_print = &stream;
776 p_stream = &stream;
777 p_info = &stream;
778 }
779
780 size_t size() { return end_bytes - start_bytes; }
781
782 protected:
783 Stream* p_stream = nullptr;
784 Print* p_print = nullptr;
786 uint32_t start_ms = 0;
787 uint32_t end_ms = UINT32_MAX;
788 uint32_t start_bytes = 0;
789 uint32_t end_bytes = UINT32_MAX;
790 uint32_t current_bytes = 0;
791 float compression_ratio = 1.0;
792
793 void consumeBytes(uint32_t len) {
794 int open = len;
795 uint8_t buffer[1024];
796 while (open > 0) {
797 int toread = min(1024, open);
798 p_stream->readBytes(buffer, toread);
799 open -= toread;
800 }
801 current_bytes += len;
802 LOGD("consumed %u -> %u", (unsigned)len, (unsigned)current_bytes);
803 }
804
806 float bytes_per_second = bytesPerSecond();
807 if (bytes_per_second > 0) {
808 start_bytes = bytes_per_second * start_ms / compression_ratio / 1000;
809 end_bytes = bytes_per_second * end_ms / compression_ratio / 1000;
810 } else {
811 LOGE("AudioInfo not defined");
812 }
813 }
814};
815
826 public:
828
829 bool begin(AudioInfo info) override {
830 setAudioInfo(info);
831 return begin();
832 }
833
834 bool begin() override {
836 // make sure that selected channels are valid
837 for (auto& out : out_channels) {
838 for (auto& ch : out.channels) {
839 if (ch > cfg.channels - 1) {
840 LOGE("Channel '%d' not valid for max %d channels", ch, cfg.channels);
841 return false;
842 }
843 }
844 }
845 return true;
846 }
847
850 void addOutput(AudioOutput& out, uint16_t channel) {
851 Vector<uint16_t> channels;
852 channels.push_back(channel);
854 def.channels = channels;
855 def.p_out = &out;
856 def.p_audio_info = &out;
857 out_channels.push_back(def);
858 }
859
862 void addOutput(AudioStream& 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(Print& out, uint16_t channel) {
875 Vector<uint16_t> channels;
876 channels.push_back(channel);
878 def.channels = channels;
879 def.p_out = &out;
880 out_channels.push_back(def);
881 }
882
885 void addOutput(Print& out, uint16_t left, uint16_t right) {
886 Vector<uint16_t> channels;
887 channels.push_back(left);
888 channels.push_back(right);
890 def.channels = channels;
891 def.p_out = &out;
892 out_channels.push_back(def);
893 }
894
897 void addOutput(AudioOutput& 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 def.p_audio_info = &out;
905 out_channels.push_back(def);
906 }
907
910 void addOutput(AudioStream& out, uint16_t left, uint16_t right) {
911 Vector<uint16_t> channels;
912 channels.push_back(left);
913 channels.push_back(right);
915 def.channels = channels;
916 def.p_out = &out;
917 def.p_audio_info = &out;
918 out_channels.push_back(def);
919 }
920
921 size_t write(const uint8_t* data, size_t len) override {
922 if (!is_active) return false;
923 LOGD("write %d", (int)len);
924 switch (cfg.bits_per_sample) {
925 case 16:
926 return writeT<int16_t>(data, len);
927 case 24:
928 return writeT<int24_t>(data, len);
929 case 32:
930 return writeT<int32_t>(data, len);
931 default:
932 return 0;
933 }
934 }
935
936 void setAudioInfo(AudioInfo ai) override {
937 this->cfg = ai;
938 // notifyAudioChange(ai);
939 for (auto& info : out_channels) {
940 auto p_notify = info.p_audio_info;
941 if (p_notify != nullptr) {
942 AudioInfo result{ai};
943 result.channels = info.channels.size();
944 p_notify->setAudioInfo(result);
945 }
946 }
947 }
948
949 protected:
957
958 template <typename T>
959 size_t writeT(const uint8_t* buffer, size_t size) {
960 if (!is_active) return 0;
961 int sample_count = size / sizeof(T);
962 // int result_size = sample_count / cfg.channels;
963 T* data = (T*)buffer;
964
965 for (int i = 0; i < sample_count; i += cfg.channels) {
966 T* frame = data + i;
967 for (auto& out : out_channels) {
968 T out_frame[out.channels.size()];
969 int ch_out = 0;
970 for (auto& ch : out.channels) {
971 // make sure we have a valid channel
972 int channel = (ch < cfg.channels) ? ch : cfg.channels - 1;
973 out_frame[ch_out++] = frame[channel];
974 }
975 // write to buffer
976 size_t written = out.buffer.writeArray((const uint8_t*)&out_frame,
977 sizeof(out_frame));
978 // write buffer to final output
979 if (out.buffer.availableForWrite() < sizeof(out_frame)) {
980 out.p_out->write(out.buffer.data(), out.buffer.available());
981 out.buffer.reset();
982 }
983 // if (written != sizeof(out_frame)) {
984 // LOGW("Could not write all samples %d -> %d", sizeof(out_frame),
985 // written);
986 // }
987 }
988 }
989 return size;
990 }
991
993 int getChannels(Print* out, int defaultChannels) {
994 for (auto& channels_select : out_channels) {
995 if (channels_select.p_out == out) return channels_select.channels.size();
996 }
997 return defaultChannels;
998 }
999};
1000
1001} // 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:411
void setOutput(AudioOutput &stream)
Definition AudioIO.h:417
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition AudioIO.h:432
AdapterAudioOutputToAudioStream(AudioOutput &stream)
Definition AudioIO.h:415
void end() override
Definition AudioIO.h:429
size_t write(const uint8_t *data, size_t len) override
Definition AudioIO.h:423
AudioOutput * p_stream
Definition AudioIO.h:437
bool begin() override
Definition AudioIO.h:427
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition AudioIO.h:419
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioIO.h:421
Wrapper which converts a AudioStream to a AudioOutput.
Definition AudioIO.h:376
void setStream(AudioStream &stream)
Definition AudioIO.h:382
virtual bool isDeletable() override
If true we need to release the related memory in the destructor.
Definition AudioIO.h:399
void end() override
Definition AudioIO.h:396
size_t write(const uint8_t *data, size_t len) override
Definition AudioIO.h:388
AdapterAudioStreamToAudioOutput(AudioStream &stream)
Definition AudioIO.h:380
int availableForWrite() override
Definition AudioIO.h:392
AudioStream * p_stream
Definition AudioIO.h:404
bool begin() override
Definition AudioIO.h:394
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition AudioIO.h:384
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioIO.h:386
Wrapper which converts a Print to a AudioOutput.
Definition AudioIO.h:353
AdapterPrintToAudioOutput(Print &print)
Definition AudioIO.h:356
AudioInfo cfg
Definition AudioIO.h:369
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition AudioIO.h:363
void setAudioInfo(AudioInfo info)
Defines the input AudioInfo.
Definition AudioIO.h:358
void setStream(Print &out)
Definition AudioIO.h:357
AudioInfo audioInfo()
provides the actual input AudioInfo
Definition AudioIO.h:365
Print * p_print
Definition AudioIO.h:368
size_t write(const uint8_t *data, size_t len)
Definition AudioIO.h:359
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:347
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:825
void addOutput(Print &out, uint16_t left, uint16_t right)
Definition AudioIO.h:885
void setAudioInfo(AudioInfo ai) override
Defines the input AudioInfo.
Definition AudioIO.h:936
void addOutput(Print &out, uint16_t channel)
Definition AudioIO.h:874
Vector< ChannelSelectionOutputDef > out_channels
Definition AudioIO.h:956
void addOutput(AudioOutput &out, uint16_t channel)
Definition AudioIO.h:850
int getChannels(Print *out, int defaultChannels)
Determine number of channels for destination.
Definition AudioIO.h:993
size_t write(const uint8_t *data, size_t len) override
Definition AudioIO.h:921
size_t writeT(const uint8_t *buffer, size_t size)
Definition AudioIO.h:959
bool begin(AudioInfo info) override
Definition AudioIO.h:829
bool begin() override
Definition AudioIO.h:834
void addOutput(AudioStream &out, uint16_t channel)
Definition AudioIO.h:862
void addOutput(AudioStream &out, uint16_t left, uint16_t right)
Definition AudioIO.h:910
void addOutput(AudioOutput &out, uint16_t left, uint16_t right)
Definition AudioIO.h:897
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:446
bool isActive(MultiOutputRecord &rec)
Definition AudioIO.h:591
void remove(Print &print)
Removes the indicated output.
Definition AudioIO.h:499
void add(AudioOutput &out)
Add an additional AudioOutput output.
Definition AudioIO.h:480
void clearInactive()
Definition AudioIO.h:558
MultiOutput(Print &out)
Definition AudioIO.h:451
Vector< MultiOutputRecord > vector
Definition AudioIO.h:586
size_t write(uint8_t ch) override
Definition AudioIO.h:539
void setAudioInfo(AudioInfo info)
Defines the input AudioInfo.
Definition AudioIO.h:514
void add(AudioStream &stream)
Add an AudioStream to the output.
Definition AudioIO.h:485
MultiOutput(AudioStream &out1, AudioStream &out2)
Defines a MultiOutput with 2 final outputs.
Definition AudioIO.h:465
size_t write(const uint8_t *data, size_t len) override
Definition AudioIO.h:522
void add(Print &print)
Definition AudioIO.h:496
void add(Client &client)
Add a (network) Client as output: e.g. WiFiClient, EthernetClient...
Definition AudioIO.h:490
MultiOutput(AudioOutput &out1, AudioOutput &out2)
Defines a MultiOutput with 2 final outputs.
Definition AudioIO.h:459
MultiOutput(AudioOutput &out)
Defines a MultiOutput with a single final outputs,.
Definition AudioIO.h:454
Kind
Definition AudioIO.h:569
MultiOutput(AudioStream &out)
Definition AudioIO.h:456
virtual ~MultiOutput()
Definition AudioIO.h:477
void clear()
Definition AudioIO.h:552
void flush()
Definition AudioIO.h:508
void setOutput(Print &out)
support for Pipleline
Definition AudioIO.h:605
MultiOutput(Print &out1, Print &out2)
Definition AudioIO.h:472
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:256
void setMaxReadSize(int size)
Defines the read buffer size for individual reads: same as transformationReader()....
Definition AudioIO.h:323
virtual void setStream(AudioStream &stream)
Defines/Changes the input & output and registers for audio change notifications.
Definition AudioIO.h:264
virtual void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioIO.h:258
TransformationReader< ReformatBaseStream > reader
Definition AudioIO.h:332
virtual float getByteFactor()=0
virtual void setOutput(Print &print) override
Defines/Changes the output target.
Definition AudioIO.h:278
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioIO.h:287
void end() override
Definition AudioIO.h:309
int available() override
Definition AudioIO.h:292
virtual Stream * getStream()
Definition AudioIO.h:285
virtual void setOutput(AudioOutput &print)
Defines/Changes the output target and registers for audio change notifications.
Definition AudioIO.h:272
Stream * p_stream
Definition AudioIO.h:333
virtual TransformationReader< ReformatBaseStream > & transformationReader()
Provides access to the TransformationReader.
Definition AudioIO.h:326
int availableForWrite() override
Definition AudioIO.h:296
void setReadResultQueueSize(int size)
same as resizeReadResultQueue(size)
Definition AudioIO.h:320
virtual Print * getPrint()
Definition AudioIO.h:283
Print * p_print
Definition AudioIO.h:334
virtual void flush()
Definition AudioIO.h:307
void setupReader()
Definition AudioIO.h:336
void resizeReadResultQueue(int size)
Definition AudioIO.h:317
Implements a typed Ringbuffer.
Definition Buffers.h:353
virtual size_t size() override
Returns the maximum capacity of the buffer.
Definition Buffers.h:440
virtual bool resize(size_t len)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:430
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition Buffers.h:184
AudioStream class that can define a start and (an optional) stop time Usually it is used to wrap an A...
Definition AudioIO.h:617
TimedStream(Print &o, long startSeconds=0, long endSeconds=-1)
Definition AudioIO.h:643
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioIO.h:757
size_t size()
Definition AudioIO.h:780
void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioIO.h:759
uint32_t end_ms
Definition AudioIO.h:787
void setEndSec(uint32_t endSeconds)
Definition AudioIO.h:664
uint32_t start_bytes
Definition AudioIO.h:788
void setEndMs(uint32_t ms)
Defines the (optional) end time in milliseconds.
Definition AudioIO.h:670
uint32_t current_bytes
Definition AudioIO.h:790
void setStream(AudioOutput &out)
Definition AudioIO.h:769
void setCompressionRatio(float ratio)
Definition AudioIO.h:750
uint32_t start_ms
Definition AudioIO.h:786
void setOutput(AudioOutput &out)
Defines/Changes the output target and registers for audio change notifications.
Definition AudioIO.h:764
size_t readBytes(uint8_t *data, size_t len) override
Definition AudioIO.h:704
void setStartSec(uint32_t startSeconds)
Definition AudioIO.h:651
TimedStream(Stream &io, long startSeconds=0, long endSeconds=-1)
Definition AudioIO.h:636
void setStream(AudioStream &stream)
Defines/Changes the input & output and registers for audio change notifications.
Definition AudioIO.h:774
TimedStream(AudioStream &io, long startSeconds=0, long endSeconds=-1)
Definition AudioIO.h:621
void consumeBytes(uint32_t len)
Definition AudioIO.h:793
int available() override
Provides the available bytes until the end time has reached.
Definition AudioIO.h:732
size_t write(const uint8_t *data, size_t len) override
Plays only data for the indiated start and end time.
Definition AudioIO.h:724
Stream * p_stream
Definition AudioIO.h:783
void setStartMs(uint32_t ms)
Defines the start time in milliseconds.
Definition AudioIO.h:657
bool isPlaying()
Returns true if we are in a valid time range and are still playing sound.
Definition AudioIO.h:676
int availableForWrite() override
Definition AudioIO.h:744
AudioInfoSupport * p_info
Definition AudioIO.h:785
bool isActive()
Returns true if we are not past the end time;.
Definition AudioIO.h:683
void calculateByteLimits()
Definition AudioIO.h:805
bool begin() override
Definition AudioIO.h:692
Print * p_print
Definition AudioIO.h:784
uint32_t end_bytes
Definition AudioIO.h:789
TimedStream(AudioOutput &o, long startSeconds=0, long endSeconds=-1)
Definition AudioIO.h:629
void setAudioInfo(AudioInfo info) override
Updates the AudioInfo in the current object and in the source or target.
Definition AudioIO.h:738
float compression_ratio
Definition AudioIO.h:791
bool begin(AudioInfo info)
Definition AudioIO.h:687
int bytesPerSecond()
Calculates the bytes per second from the AudioInfo.
Definition AudioIO.h:753
ConverterStream Helper class which implements the readBytes with the help of write.
Definition AudioIO.h:23
bool active
Definition AudioIO.h:119
QueueStream< uint8_t > result_queue
Definition AudioIO.h:115
void setupBuffers(size_t len)
Definition AudioIO.h:131
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:129
int last_setup_buffer_size
Definition AudioIO.h:122
float last_byte_factor
Definition AudioIO.h:123
void setEofOnZeroReads(bool flag)
Definition AudioIO.h:111
RingBuffer< uint8_t > result_queue_buffer
Definition AudioIO.h:114
T * p_transform
Definition AudioIO.h:118
int available()
Definition AudioIO.h:73
void restoreOutput(Print *out)
restores the original output in the converter class
Definition AudioIO.h:245
bool is_eof
Definition AudioIO.h:124
size_t total_bytes_read
Definition AudioIO.h:126
Stream * p_stream
Definition AudioIO.h:116
void fillResultQueue(size_t len)
Definition AudioIO.h:173
size_t readBytes(uint8_t *data, size_t len)
Definition AudioIO.h:47
Print * setupOutput()
Definition AudioIO.h:237
size_t getTotalBytesRead() const
Definition AudioIO.h:101
void end()
Definition AudioIO.h:83
bool eof_on_zero_reads
Definition AudioIO.h:125
int max_read_size
Definition AudioIO.h:121
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:120
Vector< uint8_t > buffer
Definition AudioIO.h:117
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:255
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:952
Vector< uint16_t > channels
Definition AudioIO.h:954
SingleBuffer< uint8_t > buffer
Definition AudioIO.h:953
Record describing a single replicated output.
Definition AudioIO.h:572
Print * print
Target to which the data is actually written.
Definition AudioIO.h:574
AudioInfoSupport * info
Definition AudioIO.h:577
MultiOutputRecord(Print *print=nullptr, AudioInfoSupport *info=nullptr, Kind kind=Kind::PrintKind)
Definition AudioIO.h:581
Kind kind
Actual type of the object behind print.
Definition AudioIO.h:579