arduino-audio-tools
Loading...
Searching...
No Matches
BaseConverter.h
Go to the documentation of this file.
1#pragma once
2#include "AudioToolsConfig.h"
5#include "AudioTypes.h"
6
15namespace audio_tools {
16
26 public:
27 BaseConverter() = default;
28 BaseConverter(BaseConverter const &) = delete;
29 virtual ~BaseConverter() = default;
30
32
33 virtual size_t convert(uint8_t *src, size_t size) = 0;
34};
35
42 public:
43 size_t convert(uint8_t(*src), size_t size) override { return size; };
44};
45
55template <typename T = int16_t>
57 public:
59 this->factor_value = factor;
60 this->maxValue = maxValue;
61 this->offset_value = offset;
62 this->channels = channels;
63 }
64
65 size_t convert(uint8_t *src, size_t byte_count) {
66 T *sample = (T *)src;
67 int size = byte_count / channels / sizeof(T);
68 for (size_t j = 0; j < size; j++) {
69 for (int i = 0; i < channels; i++) {
70 *sample = (*sample + offset_value) * factor_value;
71 if (*sample > maxValue) {
72 *sample = maxValue;
73 } else if (*sample < -maxValue) {
74 *sample = -maxValue;
75 }
76 sample++;
77 }
78 }
79 return byte_count;
80 }
81
83 void setFactor(float factor) { this->factor_value = factor; }
84
87
89 float factor() { return factor_value; }
90
92 T offset() { return offset_value; }
93
94 protected:
99};
100
106template <typename T = int16_t>
108 public:
109 ConverterAutoCenterT(int channels = 2, bool isDynamic = false) {
110 this->channels = channels;
111 this->is_dynamic = isDynamic;
112 }
113
114 void clear() { resetState(); }
115 void reset() { clear(); }
116
117 size_t convert(uint8_t(*src), size_t byte_count) override {
118 size_t size = byte_count / channels / sizeof(T);
119 T *sample = (T *)src;
120 setup((T *)src, size);
121 // convert data
122 if (is_setup) {
123 if (!is_dynamic) {
124 for (size_t j = 0; j < size; j++) {
125 for (int ch = 0; ch < channels; ch++) {
126 sample[(j * channels) + ch] =
127 sample[(j * channels) + ch] - offset_to[ch];
128 }
129 }
130 } else {
131 for (size_t j = 0; j < size; j++) {
132 for (int ch = 0; ch < channels; ch++) {
133 sample[(j * channels) + ch] = sample[(j * channels) + ch] -
134 offset_from[ch] +
135 (offset_step[ch] * size);
136 }
137 }
138 }
139 }
140 return byte_count;
141 }
142
143 protected:
148 float left = 0.0;
149 float right = 0.0;
150 bool is_setup = false;
153
154 void resetState() {
158 total.clear();
159 left = 0.0;
160 right = 0.0;
161 is_setup = false;
162 }
163
164 void setup(T *src, size_t size) {
165 if (size == 0) return;
166 if (!is_setup || is_dynamic) {
167 if (offset_from.size() == 0) {
172 }
173
174 // save last offset
175 for (int ch = 0; ch < channels; ch++) {
177 total[ch] = 0.0;
178 }
179
180 // calculate new offset
181 for (size_t j = 0; j < size; j++) {
182 for (int ch = 0; ch < channels; ch++) {
183 total[ch] += src[(j * channels) + ch];
184 }
185 }
186 for (int ch = 0; ch < channels; ch++) {
187 offset_to[ch] = total[ch] / size;
188 offset_step[ch] = (offset_to[ch] - offset_from[ch]) / size;
189 }
190 is_setup = true;
191 }
192 }
193};
194
200 public:
202
206
211
212 void end() {
213 if (p_converter != nullptr) {
214 delete p_converter;
215 p_converter = nullptr;
216 }
217 }
218
219 bool begin(AudioInfo info, bool isDynamic = false) {
220 return begin(info.channels, info.bits_per_sample, isDynamic);
221 }
222
223 bool begin(int channels, int bitsPerSample, bool isDynamic = false) {
224 // check if we need to create a new converter
225 if (p_converter != nullptr && channels == this->channels &&
226 bitsPerSample == this->bits_per_sample && isDynamic == this->is_dynamic) {
227 return true;
228 }
229 this->channels = channels;
231 this->is_dynamic = isDynamic;
232 end();
233 assert(p_converter == nullptr);
234 switch (bits_per_sample) {
235 case 8: {
237 break;
238 }
239 case 16: {
241 break;
242 }
243 case 24: {
245 break;
246 }
247 case 32: {
249 break;
250 }
251 }
252 return p_converter != nullptr;
253 }
254
255 size_t convert(uint8_t *src, size_t size) override {
256 if (p_converter == nullptr) return 0;
257 return p_converter->convert(src, size);
258 }
259
260 void clear() {
261 end();
262 if (channels > 0 && bits_per_sample > 0) {
264 }
265 }
266 void reset() { clear(); }
267
268 protected:
269 int channels = 0;
271 bool is_dynamic = false;
273};
274
283template <typename T = int16_t>
285 public:
287
288 size_t convert(uint8_t *src, size_t byte_count) override {
289 if (channels == 2) {
290 int size = byte_count / channels / sizeof(T);
291 T *sample = (T *)src;
292 for (size_t j = 0; j < size; j++) {
293 T temp = *sample;
294 *sample = *(sample + 1);
295 *(sample + 1) = temp;
296 sample += 2;
297 }
298 }
299 return byte_count;
300 }
301
302 protected:
303 int channels = 2;
304};
305
311
322template <typename T = int16_t>
324 public:
326 int channels = 2) {
327 this->channels = channels;
328 switch (config) {
329 case LeftIsEmpty:
330 left_empty = true;
331 right_empty = false;
332 is_setup = true;
333 break;
334 case RightIsEmpty:
335 left_empty = false;
336 right_empty = true;
337 is_setup = true;
338 break;
339 case Auto:
340 is_setup = false;
341 break;
342 }
343 }
344
345 size_t convert(uint8_t *src, size_t byte_count) {
346 if (channels == 2) {
347 int size = byte_count / channels / sizeof(T);
348 setup((T *)src, size);
349 if (left_empty && !right_empty) {
350 T *sample = (T *)src;
351 for (size_t j = 0; j < size; j++) {
352 *sample = *(sample + 1);
353 sample += 2;
354 }
355 } else if (!left_empty && right_empty) {
356 T *sample = (T *)src;
357 for (size_t j = 0; j < size; j++) {
358 *(sample + 1) = *sample;
359 sample += 2;
360 }
361 }
362 }
363 return byte_count;
364 }
365
366 private:
367 bool is_setup = false;
368 bool left_empty = true;
369 bool right_empty = true;
370 int channels;
371
372 void setup(T *src, size_t size) {
373 if (!is_setup) {
374 for (int j = 0; j < size; j++) {
375 if (*src != 0) {
376 left_empty = false;
377 break;
378 }
379 src += 2;
380 }
381 for (int j = 0; j < size - 1; j++) {
382 if (*(src) != 0) {
383 right_empty = false;
384 break;
385 }
386 src += 2;
387 }
388 // stop setup as soon as we found some data
389 if (!right_empty || !left_empty) {
390 is_setup = true;
391 }
392 }
393 }
394};
395
405template <typename T = int16_t>
407 public:
408 ConverterToInternalDACFormat(int channels = 2) { this->channels = channels; }
409
410 size_t convert(uint8_t *src, size_t byte_count) override {
411 int size = byte_count / channels / sizeof(T);
412 T *sample = (T *)src;
413 for (int i = 0; i < size; i++) {
414 for (int j = 0; j < channels; j++) {
415 *sample = *sample + 0x8000;
416 sample++;
417 }
418 }
419 return byte_count;
420 }
421
422 protected:
424};
425
433template <typename T = int16_t>
435 public:
436 ChannelReducerT() = default;
437
442
446
450
451 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
452
453 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
454 LOGD("convert %d -> %d", from_channels, to_channels);
456 int frame_count = size / (sizeof(T) * from_channels);
457 size_t result_size = 0;
458 T *result = (T *)target;
459 T *source = (T *)src;
461
462 for (int i = 0; i < frame_count; i++) {
463 // copy first to_channels-1
464 for (int j = 0; j < to_channels - 1; j++) {
465 *result++ = *source++;
466 result_size += sizeof(T);
467 }
468 // commbined last channels
469 T total = (int16_t)0;
470 for (int j = to_channels - 1; j < from_channels; j++) {
471 total += *source++ / reduceDiv;
472 }
473 *result++ = total;
474 result_size += sizeof(T);
475 }
476 return result_size;
477 }
478
479 protected:
482};
483
491 public:
498
499 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
500
501 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
502 switch (bits) {
503 case 8: {
505 return cr8.convert(target, src, size);
506 }
507 case 16: {
509 return cr16.convert(target, src, size);
510 }
511 case 24: {
513 return cr24.convert(target, src, size);
514 }
515 case 32: {
517 return cr32.convert(target, src, size);
518 }
519 }
520 return 0;
521 }
522
523 protected:
526 int bits;
527};
528
533template <typename T = int16_t>
534class DecimateT : public BaseConverter {
535 public:
539 count = 0; // Initialize count to 0
540 }
541
544 this->channels = channels;
545 resetState();
546 }
547
549 void setFactor(int factor) {
550 this->factor = factor;
551 resetState();
552 }
553 void clear() { resetState(); }
554 void reset() { clear(); }
555
556 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
557
558 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
559 if (!isConfigValid()) return 0;
560 if (size % (sizeof(T) * channels) > 0) {
561 LOGE("Buffer size %d is not a multiple of the number of channels %d",
562 (int)size, channels);
563 return 0;
564 }
565
566 int frame_count = size / (sizeof(T) * channels);
567 T *p_target = (T *)target;
568 T *p_source = (T *)src;
569 size_t result_size = 0;
570
571 for (int i = 0; i < frame_count; i++) {
572 if (++count == factor) {
573 count = 0;
574 // Only keep every "factor" samples
575 for (int ch = 0; ch < channels; ch++) {
576 *p_target++ = p_source[i * channels + ch]; // Corrected indexing
577 result_size += sizeof(T);
578 }
579 }
580 }
581
582 LOGD("decimate %d: %d -> %d bytes", factor, (int)size, (int)result_size);
583 return result_size;
584 }
585
586 operator bool() { return factor > 1; }
587
588 protected:
590 if (channels <= 0) {
591 LOGE("Number of channels must be > 0");
592 return false;
593 }
594 if (factor <= 0) {
595 LOGE("Decimation factor must be > 0");
596 return false;
597 }
598 return true;
599 }
600
601 void resetState() { count = 0; }
602
603 int channels = 2;
604 int factor = 1;
606};
607
614class Decimate : public BaseConverter {
615 public:
616 Decimate() = default;
617 Decimate(int factor, int channels, int bits_per_sample) {
620 setBits(bits_per_sample);
621 }
624 this->channels = channels;
625 resetState();
626 }
627 void setBits(int bits) {
628 this->bits = bits;
629 resetState();
630 }
632 void setFactor(int factor) {
633 this->factor = factor;
634 resetState();
635 }
636 ~Decimate() override { delete state; }
637 void clear() {
638 if (state != nullptr) {
639 state->reset();
640 }
641 }
642 void reset() { clear(); }
643
644 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
645 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
646 if (!isConfigValid()) return 0;
647 if (state == nullptr) {
648 switch (bits) {
649 case 8:
651 break;
652 case 16:
654 break;
655 case 24:
657 break;
658 case 32:
660 break;
661 default:
662 LOGE("Number of bits %d not supported.", bits);
663 return 0;
664 }
665 }
666 return state->convert(target, src, size);
667 }
668
669 operator bool() { return factor > 1; };
670
671 protected:
673 virtual ~DecimateState() = default;
674 virtual size_t convert(uint8_t *target, uint8_t *src, size_t size) = 0;
675 virtual void reset() = 0;
676 };
677
678 template <typename T>
681
682 size_t convert(uint8_t *target, uint8_t *src, size_t size) override {
683 return converter.convert(target, src, size);
684 }
685
686 void reset() override { converter.reset(); }
687
689 };
690
692 if (channels <= 0) {
693 LOGE("Number of channels must be > 0");
694 return false;
695 }
696 if (factor <= 0) {
697 LOGE("Decimation factor must be > 0");
698 return false;
699 }
700 return true;
701 }
702
703 void resetState() {
704 delete state;
705 state = nullptr;
706 }
707
708 int channels = 2;
709 int bits = 16;
710 int factor = 1;
712};
713
723// Helper template to define the integer type for the summation based on input
724// data type T
725template <typename T = int16_t>
727 using type = T;
728};
729
730template <>
732 using type = int16_t;
733};
734
735template <>
739
740template <>
742 using type = int32_t; // Assuming int24_t is a custom 24-bit integer type
743};
744
745template <>
749
750template <typename T = int16_t>
751class BinT : public BaseConverter {
752 public:
753 BinT() = default;
760
761 ~BinT() { delete[] this->partialBin; }
762
763 void setChannels(int channels) {
764 this->channels = channels;
765 resizeState();
766 }
767 void setBinSize(int binSize) {
768 this->binSize = binSize;
769 resetState();
770 }
771 void setAverage(bool average) { this->average = average; }
772 void clear() { resetState(); }
773 void reset() { clear(); }
774
775 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
776
777 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
778 if (!isConfigValid()) return 0;
779
780 // The binning takes the following into account
781 // 1) if size is too small it will add up data to partialBin and return 0
782 // size 2) if there is sufficient data to fill Bins but there is partial
783 // data remaining it will be added to the partial Bin 3) if there was
784 // previous partial Bin it will be filled with the new data 4) if there is
785 // insufficient new data to fill the partial Bin it will fill the partial
786 // Bin with the new data
787
788 if (size % (sizeof(T) * channels) > 0) {
789 LOGE("Buffer size %d is not a multiple of the number of channels %d",
790 (int)size, channels);
791 return 0;
792 }
793
794 T *p_target = (T *)target;
795 T *p_source = (T *)src;
796 size_t result_size = 0;
797 int sample_count = size / (sizeof(T) * channels);
798
799 for (int sample = 0; sample < sample_count; sample++) {
800 for (int ch = 0; ch < channels; ch++) {
801 partialBin[ch] += p_source[sample * channels + ch];
802 }
804
805 if (partialBinSize == binSize) {
806 for (int ch = 0; ch < channels; ch++) {
807 p_target[result_size / sizeof(T)] =
808 average ? static_cast<T>(partialBin[ch] / binSize)
809 : static_cast<T>(partialBin[ch]);
810 result_size += sizeof(T);
811 }
812 resetState();
813 }
814 }
815
816 LOGD("bin %d: processed %d samples, %d remaining, %d > %d bytes", binSize,
817 sample_count, partialBinSize, (int)size, (int)result_size);
818
819 return result_size;
820 }
821
822 protected:
824
826 if (channels <= 0) {
827 LOGE("Number of channels must be > 0");
828 return false;
829 }
830 if (binSize <= 0) {
831 LOGE("Bin size must be > 0");
832 return false;
833 }
834 return true;
835 }
836
837 void resizeState() {
838 delete[] partialBin;
839 partialBin = channels > 0 ? new SumT[channels]() : nullptr;
840 partialBinSize = 0;
841 }
842
843 void resetState() {
844 if (partialBin == nullptr && channels > 0) {
845 partialBin = new SumT[channels]();
846 } else if (partialBin != nullptr) {
847 for (int ch = 0; ch < channels; ch++) {
848 partialBin[ch] = 0;
849 }
850 }
851 partialBinSize = 0;
852 }
853
854 int channels = 2;
855 int binSize = 1;
856 bool average = true;
857 SumT *partialBin = nullptr;
859};
860
866class Bin : public BaseConverter {
867 public:
868 Bin() = default;
869 Bin(int binSize, int channels, bool average, int bits_per_sample) {
873 setBits(bits_per_sample);
874 }
875 ~Bin() override { delete state; }
876
878 this->channels = channels;
879 resetState();
880 }
881 void setBits(int bits) {
882 this->bits = bits;
883 resetState();
884 }
885 void setBinSize(int binSize) {
886 this->binSize = binSize;
887 resetState();
888 }
889 void setAverage(bool average) {
890 this->average = average;
891 resetState();
892 }
893 void clear() {
894 if (state != nullptr) {
895 state->reset();
896 }
897 }
898 void reset() { clear(); }
899
900 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
901 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
902 if (!isConfigValid()) return 0;
903 if (state == nullptr) {
904 switch (bits) {
905 case 8:
907 break;
908 case 16:
910 break;
911 case 24:
913 break;
914 case 32:
916 break;
917 default:
918 LOGE("Number of bits %d not supported.", bits);
919 return 0;
920 }
921 }
922 return state->convert(target, src, size);
923 }
924
925 protected:
926 struct BinState {
927 virtual ~BinState() = default;
928 virtual size_t convert(uint8_t *target, uint8_t *src, size_t size) = 0;
929 virtual void reset() = 0;
930 };
931
932 template <typename T>
936
937 size_t convert(uint8_t *target, uint8_t *src, size_t size) override {
938 return converter.convert(target, src, size);
939 }
940
941 void reset() override { converter.reset(); }
942
944 };
945
947 if (channels <= 0) {
948 LOGE("Number of channels must be > 0");
949 return false;
950 }
951 if (binSize <= 0) {
952 LOGE("Bin size must be > 0");
953 return false;
954 }
955 return true;
956 }
957
958 void resetState() {
959 delete state;
960 state = nullptr;
961 }
962
963 int channels = 2;
964 int bits = 16;
965 int binSize = 1;
966 bool average = false;
967 BinState *state = nullptr;
968};
969
984template <typename T = int16_t>
986 public:
988
989 size_t convert(uint8_t *src, size_t size) override {
990 return convert(src, src, size);
991 }
992
993 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
994 LOGD("channel subtract %d samples, %d bytes", (int)(size / sizeof(T)),
995 (int)size);
996
997 // Ensure the buffer size is even for pairs of channels
998 if (size % (sizeof(T) * 2) > 0) {
999 LOGE("Buffer size is not even");
1000 return 0;
1001 }
1002
1003 int sample_count =
1004 size /
1005 (sizeof(T) * 2); // Each pair of channels produces one output sample
1006 T *p_result = (T *)target;
1007 T *p_source = (T *)src;
1008
1009 for (int i = 0; i < sample_count; i++) {
1010 // *p_result++ = *p_source++ - *p_source++;
1011 auto tmp = *p_source++;
1012 tmp -= *p_source++;
1013 *p_result++ = tmp;
1014 }
1015
1016 return sizeof(T) * sample_count;
1017 }
1018};
1019
1021 public:
1022 ChannelDiff() = default;
1024 void setBits(int bits) { this->bits = bits; }
1025
1026 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
1027 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1028 switch (bits) {
1029 case 8: {
1031 return cd8.convert(target, src, size);
1032 }
1033 case 16: {
1035 return cd16.convert(target, src, size);
1036 }
1037 case 24: {
1039 return cd24.convert(target, src, size);
1040 }
1041 case 32: {
1043 return cd32.convert(target, src, size);
1044 }
1045 default: {
1046 LOGE("Number of bits %d not supported.", bits);
1047 return 0;
1048 }
1049 }
1050 }
1051
1052 protected:
1053 int bits = 16;
1054};
1055
1056
1064template <typename T = int16_t, typename SumT = float>
1066 public:
1067 ChannelMixer(int channels = 2) { this->channels = channels; }
1068 size_t convert(uint8_t *data, size_t size) {
1069 if (channels <= 1) return size; // No mixing needed for single channel
1070 T *srcT = (T *)data;
1071 T *targetT = (T *)data;
1072 int samples = size / sizeof(T);
1073 assert(samples % channels == 0);
1074 for (int j = 0; j < samples; j += channels) {
1075 SumT sum = 0;
1076 for (int ch = 0; ch < channels; ch++) {
1077 sum += srcT[j + ch];
1078 }
1079 T avg = sum / channels;
1080 for (int ch = 0; ch < channels; ch++) {
1081 targetT[j + ch] = avg;
1082 }
1083 }
1084 return size;
1085 }
1086
1087 protected:
1088 int channels = 2;
1089};
1090
1104template <typename T = int16_t, typename AvgT = float>
1106 public:
1108
1109 size_t convert(uint8_t *src, size_t size) override {
1110 return convert(src, src, size);
1111 }
1112
1113 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1114 if (size % (sizeof(T) * 2) > 0) {
1115 LOGE("Buffer size is not even");
1116 return 0;
1117 }
1118
1119 int sample_count =
1120 size /
1121 (sizeof(T) * 2); // Each pair of channels produces one output sample
1122 T *p_result = (T *)target;
1123 T *p_source = (T *)src;
1124
1125 for (int i = 0; i < sample_count; i++) {
1126 // *p_result++ = (*p_source++ + *p_source++) / 2; // Average the pair of
1127 // channels
1128 AvgT tmp = *p_source++;
1129 tmp += *p_source++;
1130 *p_result++ = tmp / 2;
1131 }
1132
1133 LOGD("channel average %d samples, %d bytes", sample_count, (int)size);
1134
1135 return sizeof(T) * sample_count;
1136 }
1137};
1138
1139
1154 public:
1155 ChannelAvg() = default;
1157 void setBits(int bits) { this->bits = bits; }
1158
1159 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
1160 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1161 switch (bits) {
1162#ifdef PREFER_FIXEDPOINT
1163 case 8: {
1165 return ca8.convert(target, src, size);
1166 }
1167 case 16: {
1169 return ca16.convert(target, src, size);
1170 }
1171 case 24: {
1173 return ca24.convert(target, src, size);
1174 }
1175#else
1176 case 8: {
1178 return ca8.convert(target, src, size);
1179 }
1180 case 16: {
1182 return ca16.convert(target, src, size);
1183 }
1184 case 24: {
1186 return ca24.convert(target, src, size);
1187 }
1188#endif
1189 case 32: {
1191 return ca32.convert(target, src, size);
1192 }
1193 default: {
1194 LOGE("Number of bits %d not supported.", bits);
1195 return 0;
1196 }
1197 }
1198 }
1199
1200 protected:
1201 int bits = 16;
1202};
1203
1217template <typename T = int16_t>
1219 public:
1220 ChannelBinDiffT() = default;
1227
1228 ~ChannelBinDiffT() { delete[] this->partialBin; }
1229
1230 void setChannels(int channels) {
1231 if ((channels % 2) > 0) {
1232 LOGE("Number of channels needs to be even");
1233 this->channels = channels + 1;
1234 } else {
1235 this->channels = channels;
1236 }
1237 resizeState();
1238 }
1240 this->binSize = binSize;
1241 resetState();
1242 }
1243 void setAverage(bool average) { this->average = average; }
1244 void clear() { resetState(); }
1245 void reset() { clear(); }
1246
1247 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
1248
1249 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1250 if (!isConfigValid()) return 0;
1251
1252 // The binning works the same as in the BinT class
1253 // Here we add subtraction before we store the bins
1254
1255 if (size % (sizeof(T) * channels) > 0) {
1256 LOGE("Buffer size needs to be multiple of channels");
1257 return 0;
1258 }
1259
1260 T *p_target = (T *)target;
1261 T *p_source = (T *)src;
1262 size_t result_size = 0;
1263 int sample_count = size / (sizeof(T) * channels);
1264
1265 for (int sample = 0; sample < sample_count; sample++) {
1266 for (int ch = 0; ch < channels; ch++) {
1267 partialBin[ch] += p_source[sample * channels + ch];
1268 }
1270
1271 if (partialBinSize == binSize) {
1272 for (int ch = 0; ch < channels; ch += 2) {
1273 SumT diff = partialBin[ch] - partialBin[ch + 1];
1274 p_target[result_size / sizeof(T)] =
1275 average ? static_cast<T>(diff / binSize)
1276 : static_cast<T>(diff);
1277 result_size += sizeof(T);
1278 }
1279 resetState();
1280 }
1281 }
1282
1283 LOGD(
1284 "bin & channel subtract %d: processed %d samples, %d remaining, %d > "
1285 "%d bytes",
1286 binSize, sample_count, partialBinSize, (int)size,
1287 (int)result_size);
1288
1289 return result_size;
1290 }
1291
1292 protected:
1294
1296 if (channels <= 0) {
1297 LOGE("Number of channels must be > 0");
1298 return false;
1299 }
1300 if (binSize <= 0) {
1301 LOGE("Bin size must be > 0");
1302 return false;
1303 }
1304 return true;
1305 }
1306
1308 delete[] partialBin;
1309 partialBin = channels > 0 ? new SumT[channels]() : nullptr;
1310 partialBinSize = 0;
1311 }
1312
1313 void resetState() {
1314 if (partialBin == nullptr && channels > 0) {
1315 partialBin = new SumT[channels]();
1316 } else if (partialBin != nullptr) {
1317 for (int ch = 0; ch < channels; ch++) {
1318 partialBin[ch] = 0;
1319 }
1320 }
1321 partialBinSize = 0;
1322 }
1323
1324 int channels = 2;
1325 int binSize = 4;
1326 bool average = true;
1327 SumT *partialBin = nullptr;
1329};
1330
1339 public:
1340 ChannelBinDiff() = default;
1341 ChannelBinDiff(int binSize, int channels, bool average, int bits_per_sample) {
1345 setBits(bits_per_sample);
1346 }
1347 ~ChannelBinDiff() override { delete state; }
1348
1350 if ((channels % 2) == 0) {
1351 this->channels = channels;
1352 } else {
1353 LOGE("Number of channels needs to be even");
1354 this->channels = channels + 1;
1355 }
1356 resetState();
1357 }
1358
1359 void setBits(int bits) {
1360 this->bits = bits;
1361 resetState();
1362 }
1364 this->binSize = binSize;
1365 resetState();
1366 }
1367 void setAverage(bool average) {
1368 this->average = average;
1369 resetState();
1370 }
1371 void clear() {
1372 if (state != nullptr) {
1373 state->reset();
1374 }
1375 }
1376 void reset() { clear(); }
1377
1378 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
1379 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1380 if (!isConfigValid()) return 0;
1381 if (state == nullptr) {
1382 switch (bits) {
1383 case 8:
1385 break;
1386 case 16:
1388 break;
1389 case 24:
1391 break;
1392 case 32:
1394 break;
1395 default:
1396 LOGE("Number of bits %d not supported.", bits);
1397 return 0;
1398 }
1399 }
1400 return state->convert(target, src, size);
1401 }
1402
1403 protected:
1405 virtual ~ChannelBinDiffState() = default;
1406 virtual size_t convert(uint8_t *target, uint8_t *src, size_t size) = 0;
1407 virtual void reset() = 0;
1408 };
1409
1410 template <typename T>
1414
1415 size_t convert(uint8_t *target, uint8_t *src, size_t size) override {
1416 return converter.convert(target, src, size);
1417 }
1418
1419 void reset() override { converter.reset(); }
1420
1422 };
1423
1425 if (channels <= 0) {
1426 LOGE("Number of channels must be > 0");
1427 return false;
1428 }
1429 if (binSize <= 0) {
1430 LOGE("Bin size must be > 0");
1431 return false;
1432 }
1433 return true;
1434 }
1435
1436 void resetState() {
1437 delete state;
1438 state = nullptr;
1439 }
1440
1441 int channels = 2;
1442 int bits = 16;
1443 int binSize = 4;
1444 bool average = true;
1446};
1447
1453template <typename T = int16_t>
1455 public:
1456 ChannelEnhancer() = default;
1457
1462
1466
1470
1471 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1472 if (from_channels == 0) return size;
1473 int frame_count = size / (sizeof(T) * from_channels);
1474 size_t result_size = 0;
1475 T *result = (T *)target;
1476 T *source = (T *)src;
1477 T value = (int16_t)0;
1478 for (int i = 0; i < frame_count; i++) {
1479 // copy available channels
1480 for (int j = 0; j < from_channels; j++) {
1481 value = *source++;
1482 *result++ = value;
1483 result_size += sizeof(T);
1484 }
1485 // repeat last value
1486 for (int j = from_channels; j < to_channels; j++) {
1487 *result++ = value;
1488 result_size += sizeof(T);
1489 }
1490 }
1491 return result_size;
1492 }
1493
1495 size_t resultSize(size_t inSize) {
1496 return inSize * to_channels / from_channels;
1497 }
1498
1499 protected:
1502};
1503
1509template <typename T = int16_t>
1511 public:
1512 ChannelConverter() = default;
1513
1518
1522
1526
1527 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1528 if (from_channels == to_channels) {
1529 memcpy(target, src, size);
1530 return size;
1531 }
1532 // setup channels
1533 if (from_channels > to_channels) {
1536 } else {
1539 }
1540
1541 // execute conversion
1542 if (from_channels > to_channels) {
1543 return reducer.convert(target, src, size);
1544 } else {
1545 return enhancer.convert(target, src, size);
1546 }
1547 }
1548
1549 protected:
1554};
1555
1561template <typename T = int16_t>
1563 public:
1565
1567
1572
1578
1579 // adds a converter
1580 void add(BaseConverter &converter) { converters.push_back(&converter); }
1581
1582 // The data is provided as int24_t tgt[][2] but returned as int24_t
1583 size_t convert(uint8_t *src, size_t size) {
1584 for (int i = 0; i < converters.size(); i++) {
1585 converters[i]->convert(src, size);
1586 }
1587 return size;
1588 }
1589
1590 private:
1591 Vector<BaseConverter *> converters;
1592};
1593
1599 public:
1601
1603
1604 bool read(int inBits, int outBits, bool outSigned, int n, int32_t *result) {
1605 bool result_bool = false;
1606 int len = inBits / 8 * n;
1607 if (stream_ptr != nullptr && stream_ptr->available() > len) {
1608 uint8_t buffer[len];
1609 stream_ptr->readBytes((uint8_t *)buffer, n * len);
1610 result_bool =
1611 toNumbers((void *)buffer, inBits, outBits, outSigned, n, result);
1612 }
1613 return result_bool;
1614 }
1615
1617 bool toNumbers(void *bufferIn, int inBits, int outBits, bool outSigned, int n,
1618 int32_t *result) {
1619 bool result_bool = false;
1620 switch (inBits) {
1621 case 8: {
1622 int8_t *buffer = (int8_t *)bufferIn;
1623 for (int j = 0; j < n; j++) {
1624 result[j] = scale(buffer[j], inBits, outBits, outSigned);
1625 }
1626 result_bool = true;
1627 } break;
1628 case 16: {
1629 int16_t *buffer = (int16_t *)bufferIn;
1630 for (int j = 0; j < n; j++) {
1631 result[j] = scale(buffer[j], inBits, outBits, outSigned);
1632 }
1633 result_bool = true;
1634 } break;
1635 case 32: {
1636 int32_t *buffer = (int32_t *)bufferIn;
1637 for (int j = 0; j < n; j++) {
1638 result[j] = scale(buffer[j], inBits, outBits, outSigned);
1639 }
1640 result_bool = true;
1641 } break;
1642 }
1643 return result_bool;
1644 }
1645
1646 protected:
1647 Stream *stream_ptr = nullptr;
1648
1650 int32_t scale(int32_t value, int inBits, int outBits, bool outSigned = true) {
1651 int32_t result = static_cast<float>(value) /
1654 if (!outSigned) {
1655 result += (NumberConverter::maxValue(outBits) / 2);
1656 }
1657 return result;
1658 }
1659};
1660
1667template <typename T = int16_t>
1669 public:
1670 Converter1Channel(Filter<T> &filter) { this->p_filter = &filter; }
1671
1672 size_t convert(uint8_t *src, size_t size) override {
1673 T *data = (T *)src;
1674 for (size_t j = 0; j < size; j++) {
1675 data[j] = p_filter->process(data[j]);
1676 }
1677 return size;
1678 }
1679
1680 protected:
1682};
1683
1690template <typename T, typename FT>
1692 public:
1695 this->channels = channels;
1696 filters.resize(channels);
1697 for (int j = 0; j < channels; j++) {
1698 filters[j] = nullptr;
1699 }
1700 }
1701
1703 void setFilter(int channel, Filter<FT> *filter) {
1704 if (channel < channels) {
1705 filters[channel] = filter;
1706 } else {
1707 LOGE("Invalid channel nummber %d - max channel is %d", channel,
1708 channels - 1);
1709 }
1710 }
1711
1713 Filter<FT> *getFilter(int channel) {
1714 if (channel < channels) return filters[channel];
1715 return nullptr;
1716 }
1717
1718
1719 // convert all samples for each channel separately
1720 size_t convert(uint8_t *src, size_t size) {
1721 int count = size / channels / sizeof(T);
1722 T *sample = (T *)src;
1723 for (size_t j = 0; j < count; j++) {
1724 for (int channel = 0; channel < channels; channel++) {
1725 if (filters[channel] != nullptr) {
1726 *sample = filters[channel]->process(*sample);
1727 }
1728 sample++;
1729 }
1730 }
1731 return size;
1732 }
1733
1734 int getChannels() { return channels; }
1735
1738 void setChannels(int newChannels) {
1739 if (newChannels == channels) return;
1740 int oldChannels = channels;
1741 channels = newChannels;
1742 filters.resize(newChannels);
1743 // initialize new slots
1744 for (int j = oldChannels; j < newChannels; j++) {
1745 filters[j] = nullptr;
1746 }
1747 }
1748
1749 protected:
1751 int channels = 0;
1752};
1753
1763template <typename T = int16_t>
1765 public:
1768 }
1769
1770 void clear() { priorLastAudioPos = n + 1; }
1771 void reset() { clear(); }
1772
1773 virtual size_t convert(uint8_t *data, size_t size) override {
1774 if (!active) {
1775 // no change to the data
1776 return size;
1777 }
1778 size_t sample_count = size / sizeof(T);
1779 size_t write_count = 0;
1780 T *audio = (T *)data;
1781
1782 // find relevant data
1783 T *p_buffer = (T *)data;
1784 for (int j = 0; j < sample_count; j++) {
1785 int pos = findLastAudioPos(audio, j);
1786 if (pos < n) {
1787 write_count++;
1788 *p_buffer++ = audio[j];
1789 }
1790 }
1791
1792 // write audio data w/o silence
1793 size_t write_size = write_count * sizeof(T);
1794 LOGI("filtered silence from %d -> %d", (int)size, (int)write_size);
1795
1796 // number of empty samples of prior buffer
1797 priorLastAudioPos = findLastAudioPos(audio, sample_count - 1);
1798
1799 // return new data size
1800 return write_size;
1801 }
1802
1803 protected:
1804 bool active = false;
1805 const uint8_t *buffer = nullptr;
1806 int n;
1809
1810 void set(int n = 5, int aplidudeLimit = 2) {
1811 LOGI("begin(n=%d, aplidudeLimit=%d", n, aplidudeLimit);
1812 this->n = n;
1813 this->amplidude_limit = aplidudeLimit;
1814 this->priorLastAudioPos = n + 1; // ignore first values
1815 this->active = n > 0;
1816 }
1817
1818 // find last position which contains audible data
1819 int findLastAudioPos(T *audio, int pos) {
1820 for (int j = 0; j < n; j++) {
1821 // we are before the start of the current buffer
1822 if (pos - j <= 0) {
1823 return priorLastAudioPos;
1824 }
1825 // we are in the current buffer
1826 if (abs(audio[pos - j]) > amplidude_limit) {
1827 return j;
1828 }
1829 }
1830 return n + 1;
1831 }
1832};
1833
1841template <typename T = int16_t>
1843 public:
1845 this->channels = channels;
1847 from_end = fromEnd;
1848 }
1849 virtual size_t convert(uint8_t *src, size_t size) {
1850 for (int ch = 0; ch < channels; ch++) {
1851 if (from_beginning)
1852 clearUpTo1stTransition(channels, ch, (T *)src, size / sizeof(T));
1853 if (from_end)
1854 clearAfterLastTransition(channels, ch, (T *)src, size / sizeof(T));
1855 }
1856 return size;
1857 }
1858
1859 protected:
1863
1864 void clearUpTo1stTransition(int channels, int channel, T *values,
1865 int sampleCount) {
1866 T first = values[channel];
1867 for (int j = 0; j < sampleCount; j += channels) {
1868 T act = values[j];
1869 if ((first <= 0.0 && act >= 0.0) || (first >= 0.0 && act <= 0.0)) {
1870 // we found the last transition so we are done
1871 break;
1872 } else {
1873 values[j] = 0;
1874 }
1875 }
1876 }
1877
1878 void clearAfterLastTransition(int channels, int channel, T *values,
1879 int sampleCount) {
1880 int lastPos = sampleCount - channels + channel;
1881 T last = values[lastPos];
1882 for (int j = lastPos; j >= 0; j -= channels) {
1883 T act = values[j];
1884 if ((last <= 0.0 && act >= 0.0) || (last >= 0.0 && act <= 0.0)) {
1885 // we found the last transition so we are done
1886 break;
1887 } else {
1888 values[j] = 0;
1889 }
1890 }
1891 }
1892};
1893
1900template <typename T = int16_t>
1902 public:
1904 float inc = 0.01) {
1905 this->channels = channels;
1906 this->inc = inc;
1908 from_end = fromEnd;
1909 }
1910 void clear() {
1911 start_factor = 0;
1912 end_factor = 0;
1913 }
1914 void reset() { clear(); }
1915 virtual size_t convert(uint8_t *src, size_t size) {
1916 int sample_count = size / sizeof(T);
1917 int frame_count = channels > 0 ? sample_count / channels : 0;
1918 if (from_beginning) processStart((T *)src, frame_count);
1919 if (from_end) processEnd((T *)src, frame_count);
1920 return size;
1921 }
1922
1923 protected:
1927 float inc = 0.01;
1928 float start_factor = 0;
1929 float end_factor = 0;
1930
1931 void processStart(T *values, int frameCount) {
1932 float factor = start_factor;
1933 for (int frame = 0; frame < frameCount; ++frame) {
1934 if (factor >= 0.8) {
1935 break;
1936 }
1937 int pos = frame * channels;
1938 for (int ch = 0; ch < channels; ++ch) {
1939 values[pos + ch] = factor * values[pos + ch];
1940 }
1941 factor += inc;
1942 }
1943 start_factor = factor;
1944 }
1945
1946 void processEnd(T *values, int frameCount) {
1947 float factor = end_factor;
1948 for (int frame = frameCount - 1; frame >= 0; --frame) {
1949 if (factor >= 0.8) {
1950 break;
1951 }
1952 int pos = frame * channels;
1953 for (int ch = 0; ch < channels; ++ch) {
1954 values[pos + ch] = factor * values[pos + ch];
1955 }
1956 factor += inc;
1957 }
1958 end_factor = factor;
1959 }
1960};
1961
1968template <typename T, size_t Cn, size_t Cx, size_t S>
1970 public:
1971 CopyChannels() : _max_val(0), _counter(0), _prev_ms(0) {}
1972
1973 size_t convert(uint8_t *src, size_t size) {
1974 T *chan = (T *)src;
1975 size_t samples = (size / Cn) / sizeof(T);
1976 for (size_t s = 0; s < samples; s++) {
1977 chan[s * Cn + Cx] = (Cx < Cn) ? chan[s * Cn + Cx] << S : 0;
1978
1979 for (size_t c = 0; c < Cn; c++) {
1980 if (c != Cx) {
1981 chan[s * Cn + c] = chan[s * Cn + Cx];
1982 }
1983 }
1984
1985 if (_max_val < chan[s * Cn]) {
1986 _max_val = chan[s * Cn];
1987 }
1988
1989 _counter++;
1990 uint32_t now = millis();
1991 if (now - _prev_ms > 1000) {
1992 _prev_ms = now;
1993 LOGI("CopyChannels samples: %u, amplitude: %d", _counter, _max_val);
1994 _max_val = 0;
1995 }
1996 }
1997 return samples * Cn * sizeof(T);
1998 }
1999
2000 private:
2001 T _max_val;
2002 uint32_t _counter;
2003 uint32_t _prev_ms;
2004};
2005
2011template <typename T = int16_t>
2013 public:
2014 size_t convert(uint8_t *src, size_t size) override {
2015 T *data = (T *)src;
2016 int samples = size / sizeof(T);
2017 for (int j = 0; j < samples; j++) {
2018 data[j] = -data[j];
2019 }
2020 return size;
2021 }
2022};
2023
2029template <typename T = int16_t>
2031 public:
2033 CallbackConverterT(T (*callback)(T in, int channel), int channels = 2) {
2035 }
2036
2037 void setCallback(T (*callback)(T in, int channel), int channels) {
2038 this->callback = callback;
2039 this->channels = channels;
2040 }
2041
2042 size_t convert(uint8_t *src, size_t size) {
2043 // no conversion if no callback is provided
2044 if (callback == nullptr) {
2045 return size;
2046 }
2047 int samples = size / sizeof(T);
2048 T *srcT = (T *)src;
2049 for (int j = 0; j < samples; j++) {
2050 srcT[j] = callback(srcT[j], j % channels);
2051 }
2052 return size;
2053 }
2054
2055 protected:
2056 T (*callback)(T in, int channel) = nullptr;
2057 int channels = 2;
2058};
2059
2062
2063} // namespace audio_tools
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
void setup()
#define assert(T)
Definition avr.h:10
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
Abstract Base class for Converters A converter is processing the data in the indicated array.
Definition BaseConverter.h:25
BaseConverter(BaseConverter const &)=delete
BaseConverter & operator=(BaseConverter const &)=delete
virtual ~BaseConverter()=default
virtual size_t convert(uint8_t *src, size_t size)=0
Provides reduced sampling rates through binning.
Definition BaseConverter.h:866
int channels
Definition BaseConverter.h:963
void setAverage(bool average)
Definition BaseConverter.h:889
~Bin() override
Definition BaseConverter.h:875
bool average
Definition BaseConverter.h:966
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:900
void resetState()
Definition BaseConverter.h:958
Bin(int binSize, int channels, bool average, int bits_per_sample)
Definition BaseConverter.h:869
BinState * state
Definition BaseConverter.h:967
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:901
void setChannels(int channels)
Definition BaseConverter.h:877
int binSize
Definition BaseConverter.h:965
void clear()
Definition BaseConverter.h:893
int bits
Definition BaseConverter.h:964
void reset()
Definition BaseConverter.h:898
void setBinSize(int binSize)
Definition BaseConverter.h:885
bool isConfigValid()
Definition BaseConverter.h:946
void setBits(int bits)
Definition BaseConverter.h:881
Definition BaseConverter.h:751
int channels
Definition BaseConverter.h:854
BinT(int binSize, int channels, bool average)
Definition BaseConverter.h:754
void setAverage(bool average)
Definition BaseConverter.h:771
bool average
Definition BaseConverter.h:856
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:775
~BinT()
Definition BaseConverter.h:761
void resetState()
Definition BaseConverter.h:843
SumT * partialBin
Definition BaseConverter.h:857
typename AppropriateSumType< T >::type SumT
Definition BaseConverter.h:823
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:777
void setChannels(int channels)
Definition BaseConverter.h:763
int binSize
Definition BaseConverter.h:855
void clear()
Definition BaseConverter.h:772
void reset()
Definition BaseConverter.h:773
int partialBinSize
Definition BaseConverter.h:858
void setBinSize(int binSize)
Definition BaseConverter.h:767
bool isConfigValid()
Definition BaseConverter.h:825
void resizeState()
Definition BaseConverter.h:837
You can provide a lambda expression to convert the data.
Definition BaseConverter.h:2030
int channels
Definition BaseConverter.h:2057
T(* callback)(T in, int channel)
Definition BaseConverter.h:2056
CallbackConverterT(T(*callback)(T in, int channel), int channels=2)
Definition BaseConverter.h:2033
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:2042
void setCallback(T(*callback)(T in, int channel), int channels)
Definition BaseConverter.h:2037
We average pairs of channels in a datastream. E.g. if we have 4 channels we end up with 2 channels....
Definition BaseConverter.h:1153
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1159
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1160
ChannelAvg(int bitsPerSample)
Definition BaseConverter.h:1156
int bits
Definition BaseConverter.h:1201
void setBits(int bits)
Definition BaseConverter.h:1157
We average pairs of channels in a datastream. E.g. if we have 4 channels we end up with 2 channels....
Definition BaseConverter.h:1105
ChannelAvgT()
Definition BaseConverter.h:1107
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:1109
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1113
Provides combination of binning and subtracting channels.
Definition BaseConverter.h:1338
int channels
Definition BaseConverter.h:1441
void setAverage(bool average)
Definition BaseConverter.h:1367
bool average
Definition BaseConverter.h:1444
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1378
void resetState()
Definition BaseConverter.h:1436
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1379
void setChannels(int channels)
Definition BaseConverter.h:1349
ChannelBinDiffState * state
Definition BaseConverter.h:1445
int binSize
Definition BaseConverter.h:1443
void clear()
Definition BaseConverter.h:1371
int bits
Definition BaseConverter.h:1442
void reset()
Definition BaseConverter.h:1376
~ChannelBinDiff() override
Definition BaseConverter.h:1347
void setBinSize(int binSize)
Definition BaseConverter.h:1363
bool isConfigValid()
Definition BaseConverter.h:1424
void setBits(int bits)
Definition BaseConverter.h:1359
ChannelBinDiff(int binSize, int channels, bool average, int bits_per_sample)
Definition BaseConverter.h:1341
We first bin the channels then we calculate the difference between pairs of channels in a datastream....
Definition BaseConverter.h:1218
int channels
Definition BaseConverter.h:1324
ChannelBinDiffT(int binSize, int channels, bool average)
Definition BaseConverter.h:1221
void setAverage(bool average)
Definition BaseConverter.h:1243
bool average
Definition BaseConverter.h:1326
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1247
void resetState()
Definition BaseConverter.h:1313
SumT * partialBin
Definition BaseConverter.h:1327
typename AppropriateSumType< T >::type SumT
Definition BaseConverter.h:1293
~ChannelBinDiffT()
Definition BaseConverter.h:1228
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1249
void setChannels(int channels)
Definition BaseConverter.h:1230
int binSize
Definition BaseConverter.h:1325
void clear()
Definition BaseConverter.h:1244
void reset()
Definition BaseConverter.h:1245
int partialBinSize
Definition BaseConverter.h:1328
void setBinSize(int binSize)
Definition BaseConverter.h:1239
bool isConfigValid()
Definition BaseConverter.h:1295
void resizeState()
Definition BaseConverter.h:1307
Increasing or decreasing the number of channels.
Definition BaseConverter.h:1510
void setTargetChannels(int channelCountOfTarget)
Definition BaseConverter.h:1523
ChannelReducerT< T > reducer
Definition BaseConverter.h:1551
int from_channels
Definition BaseConverter.h:1552
ChannelConverter(int channelCountOfTarget, int channelCountOfSource)
Definition BaseConverter.h:1514
ChannelEnhancer< T > enhancer
Definition BaseConverter.h:1550
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1527
int to_channels
Definition BaseConverter.h:1553
void setSourceChannels(int channelCountOfSource)
Definition BaseConverter.h:1519
Definition BaseConverter.h:1020
ChannelDiff(int bitsPerSample)
Definition BaseConverter.h:1023
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1026
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1027
int bits
Definition BaseConverter.h:1053
void setBits(int bits)
Definition BaseConverter.h:1024
We calculate the difference between pairs of channels in a datastream. E.g. if we have 4 channels we ...
Definition BaseConverter.h:985
ChannelDiffT()
Definition BaseConverter.h:987
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:989
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:993
Increases the channel count.
Definition BaseConverter.h:1454
ChannelEnhancer(int channelCountOfTarget, int channelCountOfSource)
Definition BaseConverter.h:1458
void setTargetChannels(int channelCountOfTarget)
Definition BaseConverter.h:1467
size_t resultSize(size_t inSize)
Determine the size of the conversion result.
Definition BaseConverter.h:1495
int from_channels
Definition BaseConverter.h:1500
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1471
int to_channels
Definition BaseConverter.h:1501
void setSourceChannels(int channelCountOfSource)
Definition BaseConverter.h:1463
We mix all input channels in a datastream. E.g. if we have stereo input data we end up with 2 identic...
Definition BaseConverter.h:1065
int channels
Definition BaseConverter.h:1088
ChannelMixer(int channels=2)
Definition BaseConverter.h:1067
size_t convert(uint8_t *data, size_t size)
Definition BaseConverter.h:1068
We combine a datastream which consists of multiple channels into less channels. E....
Definition BaseConverter.h:490
ChannelReducer(int channelCountOfTarget, int channelCountOfSource, int bitsPerSample)
Definition BaseConverter.h:492
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:499
int from_channels
Definition BaseConverter.h:524
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:501
int bits
Definition BaseConverter.h:526
int to_channels
Definition BaseConverter.h:525
We combine a datastream which consists of multiple channels into less channels. E....
Definition BaseConverter.h:434
ChannelReducerT(int channelCountOfTarget, int channelCountOfSource)
Definition BaseConverter.h:438
void setTargetChannels(int channelCountOfTarget)
Definition BaseConverter.h:447
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:451
int from_channels
Definition BaseConverter.h:480
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:453
int to_channels
Definition BaseConverter.h:481
void setSourceChannels(int channelCountOfSource)
Definition BaseConverter.h:443
Converter for 1 Channel which applies the indicated Filter.
Definition BaseConverter.h:1668
Converter1Channel(Filter< T > &filter)
Definition BaseConverter.h:1670
Filter< T > * p_filter
Definition BaseConverter.h:1681
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:1672
Makes sure that the avg of the signal is set to 0.
Definition BaseConverter.h:199
ConverterAutoCenter(int channels, int bitsPerSample)
Definition BaseConverter.h:207
BaseConverter * p_converter
Definition BaseConverter.h:272
int channels
Definition BaseConverter.h:269
bool is_dynamic
Definition BaseConverter.h:271
int bits_per_sample
Definition BaseConverter.h:270
bool begin(AudioInfo info, bool isDynamic=false)
Definition BaseConverter.h:219
ConverterAutoCenter(AudioInfo info)
Definition BaseConverter.h:203
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:255
void end()
Definition BaseConverter.h:212
bool begin(int channels, int bitsPerSample, bool isDynamic=false)
Definition BaseConverter.h:223
void clear()
Definition BaseConverter.h:260
void reset()
Definition BaseConverter.h:266
~ConverterAutoCenter()
Definition BaseConverter.h:210
Makes sure that the avg of the signal is set to 0.
Definition BaseConverter.h:107
int channels
Definition BaseConverter.h:152
bool is_dynamic
Definition BaseConverter.h:151
ConverterAutoCenterT(int channels=2, bool isDynamic=false)
Definition BaseConverter.h:109
float right
Definition BaseConverter.h:149
void resetState()
Definition BaseConverter.h:154
Vector< float > offset_to
Definition BaseConverter.h:145
float left
Definition BaseConverter.h:148
void setup(T *src, size_t size)
Definition BaseConverter.h:164
bool is_setup
Definition BaseConverter.h:150
Vector< float > offset_step
Definition BaseConverter.h:146
void clear()
Definition BaseConverter.h:114
void reset()
Definition BaseConverter.h:115
Vector< float > offset_from
Definition BaseConverter.h:144
Vector< float > total
Definition BaseConverter.h:147
size_t convert(uint8_t(*src), size_t byte_count) override
Definition BaseConverter.h:117
Make sure that both channels contain any data. We copy the data from the non-empty channel to the emp...
Definition BaseConverter.h:323
size_t convert(uint8_t *src, size_t byte_count)
Definition BaseConverter.h:345
ConverterFillLeftAndRight(FillLeftAndRightStatus config=Auto, int channels=2)
Definition BaseConverter.h:325
Inverts the signal (multiplies every sample by -1)
Definition BaseConverter.h:2012
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:2014
Converter for n Channels which applies the indicated Filter.
Definition BaseConverter.h:1691
int getChannels()
Definition BaseConverter.h:1734
int channels
Definition BaseConverter.h:1751
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1720
Vector< Filter< FT > * > filters
Definition BaseConverter.h:1750
Filter< FT > * getFilter(int channel)
returns the filter for the indicated channel
Definition BaseConverter.h:1713
void setChannels(int newChannels)
Definition BaseConverter.h:1738
void setFilter(int channel, Filter< FT > *filter)
defines the filter for an individual channel - the first channel is 0
Definition BaseConverter.h:1703
ConverterNChannels(int channels)
Default Constructor.
Definition BaseConverter.h:1694
Multiplies the values with the indicated factor adds the offset and clips at maxValue....
Definition BaseConverter.h:56
float factor_value
Definition BaseConverter.h:96
void setFactor(float factor)
Defines the factor (volume)
Definition BaseConverter.h:83
int channels
Definition BaseConverter.h:95
T offset_value
Definition BaseConverter.h:98
size_t convert(uint8_t *src, size_t byte_count)
Definition BaseConverter.h:65
T offset()
Determines the offset value.
Definition BaseConverter.h:92
ConverterScaler(float factor, T offset, T maxValue, int channels=2)
Definition BaseConverter.h:58
float factor()
Determines the actual factor (volume)
Definition BaseConverter.h:89
T maxValue
Definition BaseConverter.h:97
void setOffset(T offset)
Defines the offset.
Definition BaseConverter.h:86
Switches the left and right channel.
Definition BaseConverter.h:284
int channels
Definition BaseConverter.h:303
ConverterSwitchLeftAndRight(int channels=2)
Definition BaseConverter.h:286
size_t convert(uint8_t *src, size_t byte_count) override
Definition BaseConverter.h:288
special case for internal DAC output for the ESP32. The incomming PCM buffer needs to be converted fr...
Definition BaseConverter.h:406
int channels
Definition BaseConverter.h:423
ConverterToInternalDACFormat(int channels=2)
Definition BaseConverter.h:408
size_t convert(uint8_t *src, size_t byte_count) override
Definition BaseConverter.h:410
Copy channel Cx value of type T shifted by S bits to all Cn channels.
Definition BaseConverter.h:1969
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1973
CopyChannels()
Definition BaseConverter.h:1971
Provides a reduced sampling rate by taking a sample at every factor location (ingoring factor-1 sampl...
Definition BaseConverter.h:614
DecimateState * state
Definition BaseConverter.h:711
int channels
Definition BaseConverter.h:708
void setFactor(int factor)
Sets the factor: e.g. with 4 we keep every forth sample.
Definition BaseConverter.h:632
int factor
Definition BaseConverter.h:710
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:644
void resetState()
Definition BaseConverter.h:703
Decimate(int factor, int channels, int bits_per_sample)
Definition BaseConverter.h:617
~Decimate() override
Definition BaseConverter.h:636
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:645
void setChannels(int channels)
Defines the number of channels.
Definition BaseConverter.h:623
void clear()
Definition BaseConverter.h:637
int bits
Definition BaseConverter.h:709
void reset()
Definition BaseConverter.h:642
bool isConfigValid()
Definition BaseConverter.h:691
void setBits(int bits)
Definition BaseConverter.h:627
Provides reduced sampling rates.
Definition BaseConverter.h:534
int channels
Definition BaseConverter.h:603
void setFactor(int factor)
Sets the factor: e.g. with 4 we keep every fourth sample.
Definition BaseConverter.h:549
int factor
Definition BaseConverter.h:604
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:556
void resetState()
Definition BaseConverter.h:601
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:558
void setChannels(int channels)
Defines the number of channels.
Definition BaseConverter.h:543
DecimateT(int factor, int channels)
Definition BaseConverter.h:536
void clear()
Definition BaseConverter.h:553
void reset()
Definition BaseConverter.h:554
bool isConfigValid()
Definition BaseConverter.h:589
uint16_t count
Definition BaseConverter.h:605
Abstract filter interface definition. Subclasses implement process() to transform audio samples one a...
Definition Filter.h:32
Combines multiple converters.
Definition BaseConverter.h:1562
MultiConverter(BaseConverter &c1, BaseConverter &c2, BaseConverter &c3)
Definition BaseConverter.h:1573
MultiConverter(BaseConverter &c1)
Definition BaseConverter.h:1566
MultiConverter()
Definition BaseConverter.h:1564
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1583
MultiConverter(BaseConverter &c1, BaseConverter &c2)
Definition BaseConverter.h:1568
void add(BaseConverter &converter)
Definition BaseConverter.h:1580
Dummy converter which does nothing.
Definition BaseConverter.h:41
size_t convert(uint8_t(*src), size_t size) override
Definition BaseConverter.h:43
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition AudioTypes.h:297
Reads n numbers from an Arduino Stream.
Definition BaseConverter.h:1598
NumberReader()
Definition BaseConverter.h:1602
NumberReader(Stream &in)
Definition BaseConverter.h:1600
int32_t scale(int32_t value, int inBits, int outBits, bool outSigned=true)
scale the value
Definition BaseConverter.h:1650
Stream * stream_ptr
Definition BaseConverter.h:1647
bool toNumbers(void *bufferIn, int inBits, int outBits, bool outSigned, int n, int32_t *result)
converts a buffer to a number array
Definition BaseConverter.h:1617
bool read(int inBits, int outBits, bool outSigned, int n, int32_t *result)
Definition BaseConverter.h:1604
Big value gaps (at the beginning and the end of a recording) can lead to some popping sounds....
Definition BaseConverter.h:1842
int channels
Definition BaseConverter.h:1862
bool from_end
Definition BaseConverter.h:1861
void clearAfterLastTransition(int channels, int channel, T *values, int sampleCount)
Definition BaseConverter.h:1878
PoppingSoundRemover(int channels, bool fromBeginning, bool fromEnd)
Definition BaseConverter.h:1844
virtual size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1849
void clearUpTo1stTransition(int channels, int channel, T *values, int sampleCount)
Definition BaseConverter.h:1864
bool from_beginning
Definition BaseConverter.h:1860
Removes any silence from the buffer that is longer then n samples with a amplitude below the indicate...
Definition BaseConverter.h:1764
bool active
Definition BaseConverter.h:1804
int priorLastAudioPos
Definition BaseConverter.h:1807
virtual size_t convert(uint8_t *data, size_t size) override
Definition BaseConverter.h:1773
int findLastAudioPos(T *audio, int pos)
Definition BaseConverter.h:1819
int n
Definition BaseConverter.h:1806
void clear()
Definition BaseConverter.h:1770
int amplidude_limit
Definition BaseConverter.h:1808
void reset()
Definition BaseConverter.h:1771
void set(int n=5, int aplidudeLimit=2)
Definition BaseConverter.h:1810
SilenceRemovalConverter(int n=8, int aplidudeLimit=2)
Definition BaseConverter.h:1766
const uint8_t * buffer
Definition BaseConverter.h:1805
Changes the samples at the beginning or at the end to slowly ramp up the volume.
Definition BaseConverter.h:1901
int channels
Definition BaseConverter.h:1926
void processStart(T *values, int frameCount)
Definition BaseConverter.h:1931
float inc
Definition BaseConverter.h:1927
bool from_end
Definition BaseConverter.h:1925
virtual size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1915
float end_factor
Definition BaseConverter.h:1929
SmoothTransition(int channels, bool fromBeginning, bool fromEnd, float inc=0.01)
Definition BaseConverter.h:1903
float start_factor
Definition BaseConverter.h:1928
void clear()
Definition BaseConverter.h:1910
void processEnd(T *values, int frameCount)
Definition BaseConverter.h:1946
void reset()
Definition BaseConverter.h:1914
bool from_beginning
Definition BaseConverter.h:1924
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
void clear()
Definition Vector.h:176
bool resize(size_t newSize, T value)
Definition Vector.h:266
int size()
Definition Vector.h:178
24bit integer which is used for I2S sound processing. The values are represented as int32_t,...
Definition Int24_4bytes_t.h:22
FillLeftAndRightStatus
Configure ConverterFillLeftAndRight.
Definition BaseConverter.h:310
@ LeftIsEmpty
Definition BaseConverter.h:310
@ RightIsEmpty
Definition BaseConverter.h:310
@ Auto
Definition BaseConverter.h:310
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
uint32_t millis()
Returns the milliseconds since the start.
Definition Arduino.h:256
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
int32_t type
Definition BaseConverter.h:737
int32_t type
Definition BaseConverter.h:742
int64_t type
Definition BaseConverter.h:747
int16_t type
Definition BaseConverter.h:732
We reduce the number of samples in a datastream by summing (binning) or averaging....
Definition BaseConverter.h:726
T type
Definition BaseConverter.h:727
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
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
Definition BaseConverter.h:926
virtual ~BinState()=default
virtual size_t convert(uint8_t *target, uint8_t *src, size_t size)=0
virtual void reset()=0
Definition BaseConverter.h:933
BinT< T > converter
Definition BaseConverter.h:943
size_t convert(uint8_t *target, uint8_t *src, size_t size) override
Definition BaseConverter.h:937
BinStateT(int binSize, int channels, bool average)
Definition BaseConverter.h:934
void reset() override
Definition BaseConverter.h:941
virtual size_t convert(uint8_t *target, uint8_t *src, size_t size)=0
ChannelBinDiffT< T > converter
Definition BaseConverter.h:1421
size_t convert(uint8_t *target, uint8_t *src, size_t size) override
Definition BaseConverter.h:1415
ChannelBinDiffStateT(int binSize, int channels, bool average)
Definition BaseConverter.h:1412
void reset() override
Definition BaseConverter.h:1419
Definition BaseConverter.h:672
virtual size_t convert(uint8_t *target, uint8_t *src, size_t size)=0
Definition BaseConverter.h:679
size_t convert(uint8_t *target, uint8_t *src, size_t size) override
Definition BaseConverter.h:682
DecimateStateT(int factor, int channels)
Definition BaseConverter.h:680
DecimateT< T > converter
Definition BaseConverter.h:688
void reset() override
Definition BaseConverter.h:686