arduino-audio-tools
Loading...
Searching...
No Matches
BaseConverter.h
Go to the documentation of this file.
1#pragma once
2#include "AudioToolsConfig.h"
7#include "AudioTypes.h"
8
17namespace audio_tools {
18
28 public:
29 BaseConverter() = default;
30 BaseConverter(BaseConverter const &) = delete;
31 virtual ~BaseConverter() = default;
32
34
35 virtual size_t convert(uint8_t *src, size_t size) = 0;
36};
37
44 public:
45 size_t convert(uint8_t(*src), size_t size) override { return size; };
46};
47
57template <typename T = int16_t>
59 public:
61 this->maxValue = maxValue;
62 this->offset_value = offset;
63 this->channels = channels;
64 setFactor(factor);
65 }
66
67 size_t convert(uint8_t *src, size_t byte_count) {
68 T *sample = (T *)src;
69 int size = byte_count / channels / sizeof(T);
70 // routed through plain int (rather than T directly) so this works
71 // uniformly for every T -- soft_float_t (and, for the else branch,
72 // avoiding a second implicit conversion) only has constructors for
73 // fundamental numeric types, not for class types like int24_t
74 int mv = (int)maxValue;
75 int off = (int)offset_value;
76 for (size_t j = 0; j < size; j++) {
77 for (int i = 0; i < channels; i++) {
78 int in = (int)(*sample) + off;
79 // soft_float_t: integer mantissa/exponent under the hood, no
80 // per-sample FPU multiply
81 acc_t scaled = acc_t(in) * factor_value;
82 // clip in the wide intermediate type -- narrowing an out-of-range
83 // value straight into T (as the original code did) is undefined
84 // behavior for float-to-integer conversions
85 if (scaled > mv) {
86 scaled = mv;
87 } else if (scaled < -mv) {
88 scaled = -mv;
89 }
90 *sample = (T)(int)scaled;
91 sample++;
92 }
93 }
94 return byte_count;
95 }
96
98 void setFactor(float factor) { this->factor_value = factor; }
99
101 void setOffset(T offset) { this->offset_value = offset; }
102
104 float factor() { return factor_value; }
105
107 T offset() { return offset_value; }
108
109 protected:
110#if PREFER_FIXEDPOINT
111 using acc_t = soft_float_t;
112#else
113 using acc_t = float;
114#endif
116 // acc_t (not float): unlike q1_14_t's saturating +-2.0 range, soft_float_t
117 // has float's full dynamic range (just ~4-5 significant digits of
118 // precision), so round-tripping the getter through it doesn't risk the
119 // "set 3.0, get back a clamped 2.0" surprise that would justify keeping a
120 // separate float copy alongside it.
124};
125
131template <typename T = int16_t>
133 public:
134 ConverterAutoCenterT(int channels = 2, bool isDynamic = false) {
135 this->channels = channels;
136 this->is_dynamic = isDynamic;
137 }
138
139 void clear() { resetState(); }
140 void reset() { clear(); }
141
142 size_t convert(uint8_t(*src), size_t byte_count) override {
143 size_t size = byte_count / channels / sizeof(T);
144 T *sample = (T *)src;
145 setup((T *)src, size);
146 // convert data
147 if (is_setup) {
148 if (!is_dynamic) {
149 for (size_t j = 0; j < size; j++) {
150 for (int ch = 0; ch < channels; ch++) {
151 sample[(j * channels) + ch] = (T)(int)(
152 acc_t((int)sample[(j * channels) + ch]) - offset_to[ch]);
153 }
154 }
155 } else {
156 for (size_t j = 0; j < size; j++) {
157 for (int ch = 0; ch < channels; ch++) {
158 sample[(j * channels) + ch] =
159 (T)(int)(acc_t((int)sample[(j * channels) + ch]) -
160 offset_from[ch] + dynamic_delta[ch]);
161 }
162 }
163 }
164 }
165 return byte_count;
166 }
167
168 protected:
169#if PREFER_FIXEDPOINT
170 // soft_float_t: integer mantissa/exponent under the hood, no per-sample
171 // FPU add/subtract
172 using acc_t = soft_float_t;
173#else
174 using acc_t = float;
175#endif
178 // = offset_to - offset_from, precomputed once per block in setup() instead
179 // of every sample (the original recomputed offset_step[ch] * size --
180 // constant across the whole loop -- on every single iteration)
183 bool is_setup = false;
186
187 void resetState() {
191 total.clear();
192 is_setup = false;
193 }
194
195 void setup(T *src, size_t size) {
196 if (size == 0) return;
197 if (!is_setup || is_dynamic) {
198 if (offset_from.size() == 0) {
203 // Vector::resize() allocates via `new T[]`, which does not
204 // zero-initialize -- without this, the "save last offset" loop
205 // below would read indeterminate memory as offset_to on this very
206 // first call.
207 for (int ch = 0; ch < channels; ch++) {
208 offset_from[ch] = 0;
209 offset_to[ch] = 0;
210 dynamic_delta[ch] = 0;
211 }
212 }
213
214 // save last offset
215 for (int ch = 0; ch < channels; ch++) {
216 offset_from[ch] = offset_to[ch];
217 total[ch] = 0;
218 }
219
220 // calculate new offset
221 for (size_t j = 0; j < size; j++) {
222 for (int ch = 0; ch < channels; ch++) {
223 total[ch] += (int)src[(j * channels) + ch];
224 }
225 }
226 for (int ch = 0; ch < channels; ch++) {
227 offset_to[ch] = total[ch] / (int)size;
228 dynamic_delta[ch] = offset_to[ch] - offset_from[ch];
229 }
230 is_setup = true;
231 }
232 }
233};
234
240 public:
242
246
247 ConverterAutoCenter(int channels, int bitsPerSample) {
248 begin(channels, bitsPerSample);
249 }
251
252 void end() {
253 if (p_converter != nullptr) {
254 delete p_converter;
255 p_converter = nullptr;
256 }
257 }
258
259 bool begin(AudioInfo info, bool isDynamic = false) {
260 return begin(info.channels, info.bits_per_sample, isDynamic);
261 }
262
263 bool begin(int channels, int bitsPerSample, bool isDynamic = false) {
264 // check if we need to create a new converter
265 if (p_converter != nullptr && channels == this->channels &&
266 bitsPerSample == this->bits_per_sample && isDynamic == this->is_dynamic) {
267 return true;
268 }
269 this->channels = channels;
270 this->bits_per_sample = bitsPerSample;
271 this->is_dynamic = isDynamic;
272 end();
273 assert(p_converter == nullptr);
274 switch (bits_per_sample) {
275 case 8: {
277 break;
278 }
279 case 16: {
281 break;
282 }
283 case 24: {
285 break;
286 }
287 case 32: {
289 break;
290 }
291 }
292 return p_converter != nullptr;
293 }
294
295 size_t convert(uint8_t *src, size_t size) override {
296 if (p_converter == nullptr) return 0;
297 return p_converter->convert(src, size);
298 }
299
300 void clear() {
301 end();
302 if (channels > 0 && bits_per_sample > 0) {
304 }
305 }
306 void reset() { clear(); }
307
308 protected:
309 int channels = 0;
311 bool is_dynamic = false;
313};
314
323template <typename T = int16_t>
325 public:
327
328 size_t convert(uint8_t *src, size_t byte_count) override {
329 if (channels == 2) {
330 int size = byte_count / channels / sizeof(T);
331 T *sample = (T *)src;
332 for (size_t j = 0; j < size; j++) {
333 T temp = *sample;
334 *sample = *(sample + 1);
335 *(sample + 1) = temp;
336 sample += 2;
337 }
338 }
339 return byte_count;
340 }
341
342 protected:
343 int channels = 2;
344};
345
351
362template <typename T = int16_t>
364 public:
366 int channels = 2) {
367 this->channels = channels;
368 switch (config) {
369 case LeftIsEmpty:
370 left_empty = true;
371 right_empty = false;
372 is_setup = true;
373 break;
374 case RightIsEmpty:
375 left_empty = false;
376 right_empty = true;
377 is_setup = true;
378 break;
379 case Auto:
380 is_setup = false;
381 break;
382 }
383 }
384
385 size_t convert(uint8_t *src, size_t byte_count) {
386 if (channels == 2) {
387 int size = byte_count / channels / sizeof(T);
388 setup((T *)src, size);
389 if (left_empty && !right_empty) {
390 T *sample = (T *)src;
391 for (size_t j = 0; j < size; j++) {
392 *sample = *(sample + 1);
393 sample += 2;
394 }
395 } else if (!left_empty && right_empty) {
396 T *sample = (T *)src;
397 for (size_t j = 0; j < size; j++) {
398 *(sample + 1) = *sample;
399 sample += 2;
400 }
401 }
402 }
403 return byte_count;
404 }
405
406 private:
407 bool is_setup = false;
408 bool left_empty = true;
409 bool right_empty = true;
410 int channels;
411
412 void setup(T *src, size_t size) {
413 if (!is_setup) {
414 for (int j = 0; j < size; j++) {
415 if (*src != 0) {
416 left_empty = false;
417 break;
418 }
419 src += 2;
420 }
421 for (int j = 0; j < size - 1; j++) {
422 if (*(src) != 0) {
423 right_empty = false;
424 break;
425 }
426 src += 2;
427 }
428 // stop setup as soon as we found some data
429 if (!right_empty || !left_empty) {
430 is_setup = true;
431 }
432 }
433 }
434};
435
445template <typename T = int16_t>
447 public:
448 ConverterToInternalDACFormat(int channels = 2) { this->channels = channels; }
449
450 size_t convert(uint8_t *src, size_t byte_count) override {
451 int size = byte_count / channels / sizeof(T);
452 T *sample = (T *)src;
453 for (int i = 0; i < size; i++) {
454 for (int j = 0; j < channels; j++) {
455 *sample = *sample + 0x8000;
456 sample++;
457 }
458 }
459 return byte_count;
460 }
461
462 protected:
464};
465
473template <typename T = int16_t>
475 public:
476 ChannelReducerT() = default;
477
478 ChannelReducerT(int channelCountOfTarget, int channelCountOfSource) {
479 from_channels = channelCountOfSource;
480 to_channels = channelCountOfTarget;
481 }
482
483 void setSourceChannels(int channelCountOfSource) {
484 from_channels = channelCountOfSource;
485 }
486
487 void setTargetChannels(int channelCountOfTarget) {
488 to_channels = channelCountOfTarget;
489 }
490
491 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
492
493 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
494 LOGD("convert %d -> %d", from_channels, to_channels);
496 int frame_count = size / (sizeof(T) * from_channels);
497 size_t result_size = 0;
498 T *result = (T *)target;
499 T *source = (T *)src;
500 int reduceDiv = from_channels - to_channels + 1;
501
502 for (int i = 0; i < frame_count; i++) {
503 // copy first to_channels-1
504 for (int j = 0; j < to_channels - 1; j++) {
505 *result++ = *source++;
506 result_size += sizeof(T);
507 }
508 // commbined last channels
509 T total = (int16_t)0;
510 for (int j = to_channels - 1; j < from_channels; j++) {
511 total += *source++ / reduceDiv;
512 }
513 *result++ = total;
514 result_size += sizeof(T);
515 }
516 return result_size;
517 }
518
519 protected:
522};
523
531 public:
532 ChannelReducer(int channelCountOfTarget, int channelCountOfSource,
533 int bitsPerSample) {
534 from_channels = channelCountOfSource;
535 to_channels = channelCountOfTarget;
536 bits = bitsPerSample;
537 }
538
539 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
540
541 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
542 switch (bits) {
543 case 8: {
545 return cr8.convert(target, src, size);
546 }
547 case 16: {
549 return cr16.convert(target, src, size);
550 }
551 case 24: {
553 return cr24.convert(target, src, size);
554 }
555 case 32: {
557 return cr32.convert(target, src, size);
558 }
559 }
560 return 0;
561 }
562
563 protected:
566 int bits;
567};
568
573template <typename T = int16_t>
574class DecimateT : public BaseConverter {
575 public:
579 count = 0; // Initialize count to 0
580 }
581
584 this->channels = channels;
585 resetState();
586 }
587
589 void setFactor(int factor) {
590 this->factor = factor;
591 resetState();
592 }
593 void clear() { resetState(); }
594 void reset() { clear(); }
595
596 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
597
598 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
599 if (!isConfigValid()) return 0;
600 if (size % (sizeof(T) * channels) > 0) {
601 LOGE("Buffer size %d is not a multiple of the number of channels %d",
602 (int)size, channels);
603 return 0;
604 }
605
606 int frame_count = size / (sizeof(T) * channels);
607 T *p_target = (T *)target;
608 T *p_source = (T *)src;
609 size_t result_size = 0;
610
611 for (int i = 0; i < frame_count; i++) {
612 if (++count == factor) {
613 count = 0;
614 // Only keep every "factor" samples
615 for (int ch = 0; ch < channels; ch++) {
616 *p_target++ = p_source[i * channels + ch]; // Corrected indexing
617 result_size += sizeof(T);
618 }
619 }
620 }
621
622 LOGD("decimate %d: %d -> %d bytes", factor, (int)size, (int)result_size);
623 return result_size;
624 }
625
626 operator bool() { return factor > 1; }
627
628 protected:
630 if (channels <= 0) {
631 LOGE("Number of channels must be > 0");
632 return false;
633 }
634 if (factor <= 0) {
635 LOGE("Decimation factor must be > 0");
636 return false;
637 }
638 return true;
639 }
640
641 void resetState() { count = 0; }
642
643 int channels = 2;
644 int factor = 1;
645 uint16_t count = 0;
646};
647
654class Decimate : public BaseConverter {
655 public:
656 Decimate() = default;
657 Decimate(int factor, int channels, int bits_per_sample) {
660 setBits(bits_per_sample);
661 }
664 this->channels = channels;
665 resetState();
666 }
667 void setBits(int bits) {
668 this->bits = bits;
669 resetState();
670 }
672 void setFactor(int factor) {
673 this->factor = factor;
674 resetState();
675 }
676 ~Decimate() override { delete state; }
677 void clear() {
678 if (state != nullptr) {
679 state->reset();
680 }
681 }
682 void reset() { clear(); }
683
684 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
685 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
686 if (!isConfigValid()) return 0;
687 if (state == nullptr) {
688 switch (bits) {
689 case 8:
691 break;
692 case 16:
694 break;
695 case 24:
697 break;
698 case 32:
700 break;
701 default:
702 LOGE("Number of bits %d not supported.", bits);
703 return 0;
704 }
705 }
706 return state->convert(target, src, size);
707 }
708
709 operator bool() { return factor > 1; };
710
711 protected:
713 virtual ~DecimateState() = default;
714 virtual size_t convert(uint8_t *target, uint8_t *src, size_t size) = 0;
715 virtual void reset() = 0;
716 };
717
718 template <typename T>
721
722 size_t convert(uint8_t *target, uint8_t *src, size_t size) override {
723 return converter.convert(target, src, size);
724 }
725
726 void reset() override { converter.reset(); }
727
729 };
730
732 if (channels <= 0) {
733 LOGE("Number of channels must be > 0");
734 return false;
735 }
736 if (factor <= 0) {
737 LOGE("Decimation factor must be > 0");
738 return false;
739 }
740 return true;
741 }
742
743 void resetState() {
744 delete state;
745 state = nullptr;
746 }
747
748 int channels = 2;
749 int bits = 16;
750 int factor = 1;
752};
753
763// Helper template to define the integer type for the summation based on input
764// data type T
765template <typename T = int16_t>
767 using type = T;
768};
769
770template <>
771struct AppropriateSumType<int8_t> {
772 using type = int16_t;
773};
774
775template <>
776struct AppropriateSumType<int16_t> {
777 using type = int32_t;
778};
779
780template <>
782 using type = int32_t; // Assuming int24_t is a custom 24-bit integer type
783};
784
785template <>
786struct AppropriateSumType<int32_t> {
787 using type = int64_t;
788};
789
790template <typename T = int16_t>
791class BinT : public BaseConverter {
792 public:
793 BinT() = default;
800
801 ~BinT() { delete[] this->partialBin; }
802
803 void setChannels(int channels) {
804 this->channels = channels;
805 resizeState();
806 }
807 void setBinSize(int binSize) {
808 this->binSize = binSize;
809 resetState();
810 }
811 void setAverage(bool average) { this->average = average; }
812 void clear() { resetState(); }
813 void reset() { clear(); }
814
815 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
816
817 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
818 if (!isConfigValid()) return 0;
819
820 // The binning takes the following into account
821 // 1) if size is too small it will add up data to partialBin and return 0
822 // size 2) if there is sufficient data to fill Bins but there is partial
823 // data remaining it will be added to the partial Bin 3) if there was
824 // previous partial Bin it will be filled with the new data 4) if there is
825 // insufficient new data to fill the partial Bin it will fill the partial
826 // Bin with the new data
827
828 if (size % (sizeof(T) * channels) > 0) {
829 LOGE("Buffer size %d is not a multiple of the number of channels %d",
830 (int)size, channels);
831 return 0;
832 }
833
834 T *p_target = (T *)target;
835 T *p_source = (T *)src;
836 size_t result_size = 0;
837 int sample_count = size / (sizeof(T) * channels);
838
839 for (int sample = 0; sample < sample_count; sample++) {
840 for (int ch = 0; ch < channels; ch++) {
841 partialBin[ch] += p_source[sample * channels + ch];
842 }
844
845 if (partialBinSize == binSize) {
846 for (int ch = 0; ch < channels; ch++) {
847 p_target[result_size / sizeof(T)] =
848 average ? static_cast<T>(partialBin[ch] / binSize)
849 : static_cast<T>(partialBin[ch]);
850 result_size += sizeof(T);
851 }
852 resetState();
853 }
854 }
855
856 LOGD("bin %d: processed %d samples, %d remaining, %d > %d bytes", binSize,
857 sample_count, partialBinSize, (int)size, (int)result_size);
858
859 return result_size;
860 }
861
862 protected:
864
866 if (channels <= 0) {
867 LOGE("Number of channels must be > 0");
868 return false;
869 }
870 if (binSize <= 0) {
871 LOGE("Bin size must be > 0");
872 return false;
873 }
874 return true;
875 }
876
877 void resizeState() {
878 delete[] partialBin;
879 partialBin = channels > 0 ? new SumT[channels]() : nullptr;
880 partialBinSize = 0;
881 }
882
883 void resetState() {
884 if (partialBin == nullptr && channels > 0) {
885 partialBin = new SumT[channels]();
886 } else if (partialBin != nullptr) {
887 for (int ch = 0; ch < channels; ch++) {
888 partialBin[ch] = 0;
889 }
890 }
891 partialBinSize = 0;
892 }
893
894 int channels = 2;
895 int binSize = 1;
896 bool average = true;
897 SumT *partialBin = nullptr;
899};
900
906class Bin : public BaseConverter {
907 public:
908 Bin() = default;
909 Bin(int binSize, int channels, bool average, int bits_per_sample) {
913 setBits(bits_per_sample);
914 }
915 ~Bin() override { delete state; }
916
918 this->channels = channels;
919 resetState();
920 }
921 void setBits(int bits) {
922 this->bits = bits;
923 resetState();
924 }
925 void setBinSize(int binSize) {
926 this->binSize = binSize;
927 resetState();
928 }
929 void setAverage(bool average) {
930 this->average = average;
931 resetState();
932 }
933 void clear() {
934 if (state != nullptr) {
935 state->reset();
936 }
937 }
938 void reset() { clear(); }
939
940 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
941 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
942 if (!isConfigValid()) return 0;
943 if (state == nullptr) {
944 switch (bits) {
945 case 8:
947 break;
948 case 16:
950 break;
951 case 24:
953 break;
954 case 32:
956 break;
957 default:
958 LOGE("Number of bits %d not supported.", bits);
959 return 0;
960 }
961 }
962 return state->convert(target, src, size);
963 }
964
965 protected:
966 struct BinState {
967 virtual ~BinState() = default;
968 virtual size_t convert(uint8_t *target, uint8_t *src, size_t size) = 0;
969 virtual void reset() = 0;
970 };
971
972 template <typename T>
976
977 size_t convert(uint8_t *target, uint8_t *src, size_t size) override {
978 return converter.convert(target, src, size);
979 }
980
981 void reset() override { converter.reset(); }
982
984 };
985
987 if (channels <= 0) {
988 LOGE("Number of channels must be > 0");
989 return false;
990 }
991 if (binSize <= 0) {
992 LOGE("Bin size must be > 0");
993 return false;
994 }
995 return true;
996 }
997
998 void resetState() {
999 delete state;
1000 state = nullptr;
1001 }
1002
1003 int channels = 2;
1004 int bits = 16;
1005 int binSize = 1;
1006 bool average = false;
1007 BinState *state = nullptr;
1008};
1009
1024template <typename T = int16_t>
1026 public:
1028
1029 size_t convert(uint8_t *src, size_t size) override {
1030 return convert(src, src, size);
1031 }
1032
1033 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1034 LOGD("channel subtract %d samples, %d bytes", (int)(size / sizeof(T)),
1035 (int)size);
1036
1037 // Ensure the buffer size is even for pairs of channels
1038 if (size % (sizeof(T) * 2) > 0) {
1039 LOGE("Buffer size is not even");
1040 return 0;
1041 }
1042
1043 int sample_count =
1044 size /
1045 (sizeof(T) * 2); // Each pair of channels produces one output sample
1046 T *p_result = (T *)target;
1047 T *p_source = (T *)src;
1048
1049 for (int i = 0; i < sample_count; i++) {
1050 // *p_result++ = *p_source++ - *p_source++;
1051 auto tmp = *p_source++;
1052 tmp -= *p_source++;
1053 *p_result++ = tmp;
1054 }
1055
1056 return sizeof(T) * sample_count;
1057 }
1058};
1059
1061 public:
1062 ChannelDiff() = default;
1063 ChannelDiff(int bitsPerSample) { setBits(bitsPerSample); }
1064 void setBits(int bits) { this->bits = bits; }
1065
1066 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
1067 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1068 switch (bits) {
1069 case 8: {
1071 return cd8.convert(target, src, size);
1072 }
1073 case 16: {
1075 return cd16.convert(target, src, size);
1076 }
1077 case 24: {
1079 return cd24.convert(target, src, size);
1080 }
1081 case 32: {
1083 return cd32.convert(target, src, size);
1084 }
1085 default: {
1086 LOGE("Number of bits %d not supported.", bits);
1087 return 0;
1088 }
1089 }
1090 }
1091
1092 protected:
1093 int bits = 16;
1094};
1095
1096
1104#if PREFER_FIXEDPOINT
1105// soft_float_t: integer mantissa/exponent under the hood, so the per-sample
1106// accumulation avoids the FPU without a per-bit-depth dispatch (like
1107// ChannelAvg's) being needed here
1108template <typename T = int16_t, typename SumT = soft_float_t>
1109#else
1110template <typename T = int16_t, typename SumT = float>
1111#endif
1113 public:
1114 ChannelMixer(int channels = 2) { this->channels = channels; }
1115 size_t convert(uint8_t *data, size_t size) {
1116 if (channels <= 1) return size; // No mixing needed for single channel
1117 T *srcT = (T *)data;
1118 T *targetT = (T *)data;
1119 int samples = size / sizeof(T);
1120 assert(samples % channels == 0);
1121 for (int j = 0; j < samples; j += channels) {
1122 SumT sum = 0;
1123 for (int ch = 0; ch < channels; ch++) {
1124 sum += (SumT)srcT[j + ch];
1125 }
1126 T avg = (T)(sum / channels);
1127 for (int ch = 0; ch < channels; ch++) {
1128 targetT[j + ch] = avg;
1129 }
1130 }
1131 return size;
1132 }
1133
1134 protected:
1135 int channels = 2;
1136};
1137
1151template <typename T = int16_t, typename AvgT = float>
1153 public:
1155
1156 size_t convert(uint8_t *src, size_t size) override {
1157 return convert(src, src, size);
1158 }
1159
1160 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1161 if (size % (sizeof(T) * 2) > 0) {
1162 LOGE("Buffer size is not even");
1163 return 0;
1164 }
1165
1166 int sample_count =
1167 size /
1168 (sizeof(T) * 2); // Each pair of channels produces one output sample
1169 T *p_result = (T *)target;
1170 T *p_source = (T *)src;
1171
1172 for (int i = 0; i < sample_count; i++) {
1173 // *p_result++ = (*p_source++ + *p_source++) / 2; // Average the pair of
1174 // channels
1175 AvgT tmp = *p_source++;
1176 tmp += *p_source++;
1177 *p_result++ = tmp / 2;
1178 }
1179
1180 LOGD("channel average %d samples, %d bytes", sample_count, (int)size);
1181
1182 return sizeof(T) * sample_count;
1183 }
1184};
1185
1186
1201 public:
1202 ChannelAvg() = default;
1203 ChannelAvg(int bitsPerSample) { setBits(bitsPerSample); }
1204 void setBits(int bits) { this->bits = bits; }
1205
1206 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
1207 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1208 switch (bits) {
1209#if PREFER_FIXEDPOINT
1210 case 8: {
1212 return ca8.convert(target, src, size);
1213 }
1214 case 16: {
1216 return ca16.convert(target, src, size);
1217 }
1218 case 24: {
1220 return ca24.convert(target, src, size);
1221 }
1222 case 32: {
1224 return ca32.convert(target, src, size);
1225 }
1226#else
1227 case 8: {
1229 return ca8.convert(target, src, size);
1230 }
1231 case 16: {
1233 return ca16.convert(target, src, size);
1234 }
1235 case 24: {
1237 return ca24.convert(target, src, size);
1238 }
1239 case 32: {
1241 return ca32.convert(target, src, size);
1242 }
1243#endif
1244 default: {
1245 LOGE("Number of bits %d not supported.", bits);
1246 return 0;
1247 }
1248 }
1249 }
1250
1251 protected:
1252 int bits = 16;
1253};
1254
1268template <typename T = int16_t>
1270 public:
1271 ChannelBinDiffT() = default;
1278
1279 ~ChannelBinDiffT() { delete[] this->partialBin; }
1280
1281 void setChannels(int channels) {
1282 if ((channels % 2) > 0) {
1283 LOGE("Number of channels needs to be even");
1284 this->channels = channels + 1;
1285 } else {
1286 this->channels = channels;
1287 }
1288 resizeState();
1289 }
1291 this->binSize = binSize;
1292 resetState();
1293 }
1294 void setAverage(bool average) { this->average = average; }
1295 void clear() { resetState(); }
1296 void reset() { clear(); }
1297
1298 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
1299
1300 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1301 if (!isConfigValid()) return 0;
1302
1303 // The binning works the same as in the BinT class
1304 // Here we add subtraction before we store the bins
1305
1306 if (size % (sizeof(T) * channels) > 0) {
1307 LOGE("Buffer size needs to be multiple of channels");
1308 return 0;
1309 }
1310
1311 T *p_target = (T *)target;
1312 T *p_source = (T *)src;
1313 size_t result_size = 0;
1314 int sample_count = size / (sizeof(T) * channels);
1315
1316 for (int sample = 0; sample < sample_count; sample++) {
1317 for (int ch = 0; ch < channels; ch++) {
1318 partialBin[ch] += p_source[sample * channels + ch];
1319 }
1321
1322 if (partialBinSize == binSize) {
1323 for (int ch = 0; ch < channels; ch += 2) {
1324 SumT diff = partialBin[ch] - partialBin[ch + 1];
1325 p_target[result_size / sizeof(T)] =
1326 average ? static_cast<T>(diff / binSize)
1327 : static_cast<T>(diff);
1328 result_size += sizeof(T);
1329 }
1330 resetState();
1331 }
1332 }
1333
1334 LOGD(
1335 "bin & channel subtract %d: processed %d samples, %d remaining, %d > "
1336 "%d bytes",
1337 binSize, sample_count, partialBinSize, (int)size,
1338 (int)result_size);
1339
1340 return result_size;
1341 }
1342
1343 protected:
1345
1347 if (channels <= 0) {
1348 LOGE("Number of channels must be > 0");
1349 return false;
1350 }
1351 if (binSize <= 0) {
1352 LOGE("Bin size must be > 0");
1353 return false;
1354 }
1355 return true;
1356 }
1357
1359 delete[] partialBin;
1360 partialBin = channels > 0 ? new SumT[channels]() : nullptr;
1361 partialBinSize = 0;
1362 }
1363
1364 void resetState() {
1365 if (partialBin == nullptr && channels > 0) {
1366 partialBin = new SumT[channels]();
1367 } else if (partialBin != nullptr) {
1368 for (int ch = 0; ch < channels; ch++) {
1369 partialBin[ch] = 0;
1370 }
1371 }
1372 partialBinSize = 0;
1373 }
1374
1375 int channels = 2;
1376 int binSize = 4;
1377 bool average = true;
1378 SumT *partialBin = nullptr;
1380};
1381
1390 public:
1391 ChannelBinDiff() = default;
1392 ChannelBinDiff(int binSize, int channels, bool average, int bits_per_sample) {
1396 setBits(bits_per_sample);
1397 }
1398 ~ChannelBinDiff() override { delete state; }
1399
1401 if ((channels % 2) == 0) {
1402 this->channels = channels;
1403 } else {
1404 LOGE("Number of channels needs to be even");
1405 this->channels = channels + 1;
1406 }
1407 resetState();
1408 }
1409
1410 void setBits(int bits) {
1411 this->bits = bits;
1412 resetState();
1413 }
1415 this->binSize = binSize;
1416 resetState();
1417 }
1418 void setAverage(bool average) {
1419 this->average = average;
1420 resetState();
1421 }
1422 void clear() {
1423 if (state != nullptr) {
1424 state->reset();
1425 }
1426 }
1427 void reset() { clear(); }
1428
1429 size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
1430 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1431 if (!isConfigValid()) return 0;
1432 if (state == nullptr) {
1433 switch (bits) {
1434 case 8:
1436 break;
1437 case 16:
1439 break;
1440 case 24:
1442 break;
1443 case 32:
1445 break;
1446 default:
1447 LOGE("Number of bits %d not supported.", bits);
1448 return 0;
1449 }
1450 }
1451 return state->convert(target, src, size);
1452 }
1453
1454 protected:
1456 virtual ~ChannelBinDiffState() = default;
1457 virtual size_t convert(uint8_t *target, uint8_t *src, size_t size) = 0;
1458 virtual void reset() = 0;
1459 };
1460
1461 template <typename T>
1465
1466 size_t convert(uint8_t *target, uint8_t *src, size_t size) override {
1467 return converter.convert(target, src, size);
1468 }
1469
1470 void reset() override { converter.reset(); }
1471
1473 };
1474
1476 if (channels <= 0) {
1477 LOGE("Number of channels must be > 0");
1478 return false;
1479 }
1480 if (binSize <= 0) {
1481 LOGE("Bin size must be > 0");
1482 return false;
1483 }
1484 return true;
1485 }
1486
1487 void resetState() {
1488 delete state;
1489 state = nullptr;
1490 }
1491
1492 int channels = 2;
1493 int bits = 16;
1494 int binSize = 4;
1495 bool average = true;
1497};
1498
1504template <typename T = int16_t>
1506 public:
1507 ChannelEnhancer() = default;
1508
1509 ChannelEnhancer(int channelCountOfTarget, int channelCountOfSource) {
1510 from_channels = channelCountOfSource;
1511 to_channels = channelCountOfTarget;
1512 }
1513
1514 void setSourceChannels(int channelCountOfSource) {
1515 from_channels = channelCountOfSource;
1516 }
1517
1518 void setTargetChannels(int channelCountOfTarget) {
1519 to_channels = channelCountOfTarget;
1520 }
1521
1522 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1523 if (from_channels == 0) return size;
1524 int frame_count = size / (sizeof(T) * from_channels);
1525 size_t result_size = 0;
1526 T *result = (T *)target;
1527 T *source = (T *)src;
1528 T value = (int16_t)0;
1529 for (int i = 0; i < frame_count; i++) {
1530 // copy available channels
1531 for (int j = 0; j < from_channels; j++) {
1532 value = *source++;
1533 *result++ = value;
1534 result_size += sizeof(T);
1535 }
1536 // repeat last value
1537 for (int j = from_channels; j < to_channels; j++) {
1538 *result++ = value;
1539 result_size += sizeof(T);
1540 }
1541 }
1542 return result_size;
1543 }
1544
1546 size_t resultSize(size_t inSize) {
1547 return inSize * to_channels / from_channels;
1548 }
1549
1550 protected:
1553};
1554
1560template <typename T = int16_t>
1562 public:
1563 ChannelConverter() = default;
1564
1565 ChannelConverter(int channelCountOfTarget, int channelCountOfSource) {
1566 from_channels = channelCountOfSource;
1567 to_channels = channelCountOfTarget;
1568 }
1569
1570 void setSourceChannels(int channelCountOfSource) {
1571 from_channels = channelCountOfSource;
1572 }
1573
1574 void setTargetChannels(int channelCountOfTarget) {
1575 to_channels = channelCountOfTarget;
1576 }
1577
1578 size_t convert(uint8_t *target, uint8_t *src, size_t size) {
1579 if (from_channels == to_channels) {
1580 memcpy(target, src, size);
1581 return size;
1582 }
1583 // setup channels
1584 if (from_channels > to_channels) {
1587 } else {
1590 }
1591
1592 // execute conversion
1593 if (from_channels > to_channels) {
1594 return reducer.convert(target, src, size);
1595 } else {
1596 return enhancer.convert(target, src, size);
1597 }
1598 }
1599
1600 protected:
1605};
1606
1612template <typename T = int16_t>
1614 public:
1616
1618
1620 add(c1);
1621 add(c2);
1622 }
1623
1625 add(c1);
1626 add(c2);
1627 add(c3);
1628 }
1629
1630 // adds a converter
1631 void add(BaseConverter &converter) { converters.push_back(&converter); }
1632
1633 // The data is provided as int24_t tgt[][2] but returned as int24_t
1634 size_t convert(uint8_t *src, size_t size) {
1635 for (int i = 0; i < converters.size(); i++) {
1636 converters[i]->convert(src, size);
1637 }
1638 return size;
1639 }
1640
1641 private:
1642 Vector<BaseConverter *> converters;
1643};
1644
1650 public:
1652
1654
1655 bool read(int inBits, int outBits, bool outSigned, int n, int32_t *result) {
1656 bool result_bool = false;
1657 int len = inBits / 8 * n;
1658 if (stream_ptr != nullptr && stream_ptr->available() > len) {
1659 uint8_t buffer[len];
1660 stream_ptr->readBytes((uint8_t *)buffer, n * len);
1661 result_bool =
1662 toNumbers((void *)buffer, inBits, outBits, outSigned, n, result);
1663 }
1664 return result_bool;
1665 }
1666
1668 bool toNumbers(void *bufferIn, int inBits, int outBits, bool outSigned, int n,
1669 int32_t *result) {
1670 bool result_bool = false;
1671 switch (inBits) {
1672 case 8: {
1673 int8_t *buffer = (int8_t *)bufferIn;
1674 for (int j = 0; j < n; j++) {
1675 result[j] = scale(buffer[j], inBits, outBits, outSigned);
1676 }
1677 result_bool = true;
1678 } break;
1679 case 16: {
1680 int16_t *buffer = (int16_t *)bufferIn;
1681 for (int j = 0; j < n; j++) {
1682 result[j] = scale(buffer[j], inBits, outBits, outSigned);
1683 }
1684 result_bool = true;
1685 } break;
1686 case 32: {
1687 int32_t *buffer = (int32_t *)bufferIn;
1688 for (int j = 0; j < n; j++) {
1689 result[j] = scale(buffer[j], inBits, outBits, outSigned);
1690 }
1691 result_bool = true;
1692 } break;
1693 }
1694 return result_bool;
1695 }
1696
1697 protected:
1698 Stream *stream_ptr = nullptr;
1699
1701 int32_t scale(int32_t value, int inBits, int outBits, bool outSigned = true) {
1702 int32_t result = static_cast<float>(value) /
1705 if (!outSigned) {
1706 result += (NumberConverter::maxValue(outBits) / 2);
1707 }
1708 return result;
1709 }
1710};
1711
1718template <typename T = int16_t>
1720 public:
1721 Converter1Channel(Filter<T> &filter) { this->p_filter = &filter; }
1722
1723 size_t convert(uint8_t *src, size_t size) override {
1724 T *data = (T *)src;
1725 for (size_t j = 0; j < size; j++) {
1726 data[j] = p_filter->process(data[j]);
1727 }
1728 return size;
1729 }
1730
1731 protected:
1733};
1734
1748template <typename T, typename FT>
1750 static FT toFilterType(T sample) { return (FT)sample; }
1751 static T fromFilterType(FT value) { return (T)value; }
1752};
1753
1754template <>
1756 static q1_14_t toFilterType(int16_t sample) {
1757 return q1_14_t::fromInt16(sample);
1758 }
1759 static int16_t fromFilterType(q1_14_t value) { return value.toInt16(); }
1760};
1761
1762template <>
1765 return q1_14_t::fromInt24(sample);
1766 }
1767 static int24_t fromFilterType(q1_14_t value) { return value.toInt24(); }
1768};
1769
1770template <>
1772 static q1_14_t toFilterType(int32_t sample) {
1773 return q1_14_t::fromInt32(sample);
1774 }
1775 static int32_t fromFilterType(q1_14_t value) { return value.toInt32(); }
1776};
1777
1784template <typename T, typename FT>
1786 public:
1789 this->channels = channels;
1790 filters.resize(channels);
1791 for (int j = 0; j < channels; j++) {
1792 filters[j] = nullptr;
1793 }
1794 }
1795
1797 void setFilter(int channel, Filter<FT> *filter) {
1798 if (channel < channels) {
1799 filters[channel] = filter;
1800 } else {
1801 LOGE("Invalid channel nummber %d - max channel is %d", channel,
1802 channels - 1);
1803 }
1804 }
1805
1807 Filter<FT> *getFilter(int channel) {
1808 if (channel < channels) return filters[channel];
1809 return nullptr;
1810 }
1811
1812
1813 // convert all samples for each channel separately
1814 size_t convert(uint8_t *src, size_t size) {
1815 int count = size / channels / sizeof(T);
1816 T *sample = (T *)src;
1817 for (size_t j = 0; j < count; j++) {
1818 for (int channel = 0; channel < channels; channel++) {
1819 if (filters[channel] != nullptr) {
1821 FT out = filters[channel]->process(in);
1823 }
1824 sample++;
1825 }
1826 }
1827 return size;
1828 }
1829
1830 int getChannels() { return channels; }
1831
1834 void setChannels(int newChannels) {
1835 if (newChannels == channels) return;
1836 int oldChannels = channels;
1837 channels = newChannels;
1838 filters.resize(newChannels);
1839 // initialize new slots
1840 for (int j = oldChannels; j < newChannels; j++) {
1841 filters[j] = nullptr;
1842 }
1843 }
1844
1845 protected:
1847 int channels = 0;
1848};
1849
1859template <typename T = int16_t>
1861 public:
1862 SilenceRemovalConverter(int n = 8, int aplidudeLimit = 2) {
1863 set(n, aplidudeLimit);
1864 }
1865
1866 void clear() { priorLastAudioPos = n + 1; }
1867 void reset() { clear(); }
1868
1869 virtual size_t convert(uint8_t *data, size_t size) override {
1870 if (!active) {
1871 // no change to the data
1872 return size;
1873 }
1874 size_t sample_count = size / sizeof(T);
1875 size_t write_count = 0;
1876 T *audio = (T *)data;
1877
1878 // find relevant data
1879 T *p_buffer = (T *)data;
1880 for (int j = 0; j < sample_count; j++) {
1881 int pos = findLastAudioPos(audio, j);
1882 if (pos < n) {
1883 write_count++;
1884 *p_buffer++ = audio[j];
1885 }
1886 }
1887
1888 // write audio data w/o silence
1889 size_t write_size = write_count * sizeof(T);
1890 LOGI("filtered silence from %d -> %d", (int)size, (int)write_size);
1891
1892 // number of empty samples of prior buffer
1893 priorLastAudioPos = findLastAudioPos(audio, sample_count - 1);
1894
1895 // return new data size
1896 return write_size;
1897 }
1898
1899 protected:
1900 bool active = false;
1901 const uint8_t *buffer = nullptr;
1902 int n;
1905
1906 void set(int n = 5, int aplidudeLimit = 2) {
1907 LOGI("begin(n=%d, aplidudeLimit=%d", n, aplidudeLimit);
1908 this->n = n;
1909 this->amplidude_limit = aplidudeLimit;
1910 this->priorLastAudioPos = n + 1; // ignore first values
1911 this->active = n > 0;
1912 }
1913
1914 // find last position which contains audible data
1915 int findLastAudioPos(T *audio, int pos) {
1916 for (int j = 0; j < n; j++) {
1917 // we are before the start of the current buffer
1918 if (pos - j <= 0) {
1919 return priorLastAudioPos;
1920 }
1921 // we are in the current buffer
1922 if (abs(audio[pos - j]) > amplidude_limit) {
1923 return j;
1924 }
1925 }
1926 return n + 1;
1927 }
1928};
1929
1937template <typename T = int16_t>
1939 public:
1940 PoppingSoundRemover(int channels, bool fromBeginning, bool fromEnd) {
1941 this->channels = channels;
1942 from_beginning = fromBeginning;
1943 from_end = fromEnd;
1944 }
1945 virtual size_t convert(uint8_t *src, size_t size) {
1946 for (int ch = 0; ch < channels; ch++) {
1947 if (from_beginning)
1948 clearUpTo1stTransition(channels, ch, (T *)src, size / sizeof(T));
1949 if (from_end)
1950 clearAfterLastTransition(channels, ch, (T *)src, size / sizeof(T));
1951 }
1952 return size;
1953 }
1954
1955 protected:
1959
1960 void clearUpTo1stTransition(int channels, int channel, T *values,
1961 int sampleCount) {
1962 T first = values[channel];
1963 for (int j = 0; j < sampleCount; j += channels) {
1964 T act = values[j];
1965 if ((first <= 0.0 && act >= 0.0) || (first >= 0.0 && act <= 0.0)) {
1966 // we found the last transition so we are done
1967 break;
1968 } else {
1969 values[j] = 0;
1970 }
1971 }
1972 }
1973
1974 void clearAfterLastTransition(int channels, int channel, T *values,
1975 int sampleCount) {
1976 int lastPos = sampleCount - channels + channel;
1977 T last = values[lastPos];
1978 for (int j = lastPos; j >= 0; j -= channels) {
1979 T act = values[j];
1980 if ((last <= 0.0 && act >= 0.0) || (last >= 0.0 && act <= 0.0)) {
1981 // we found the last transition so we are done
1982 break;
1983 } else {
1984 values[j] = 0;
1985 }
1986 }
1987 }
1988};
1989
1996template <typename T = int16_t>
1998 public:
1999 SmoothTransition(int channels, bool fromBeginning, bool fromEnd,
2000 float inc = 0.01) {
2001 this->channels = channels;
2002 this->inc = inc;
2003 from_beginning = fromBeginning;
2004 from_end = fromEnd;
2005 }
2006 void clear() {
2007 start_factor = 0;
2008 end_factor = 0;
2009 }
2010 void reset() { clear(); }
2011 virtual size_t convert(uint8_t *src, size_t size) {
2012 int sample_count = size / sizeof(T);
2013 int frame_count = channels > 0 ? sample_count / channels : 0;
2014 if (from_beginning) processStart((T *)src, frame_count);
2015 if (from_end) processEnd((T *)src, frame_count);
2016 return size;
2017 }
2018
2019 protected:
2023 float inc = 0.01;
2024 float start_factor = 0;
2025 float end_factor = 0;
2026
2027 void processStart(T *values, int frameCount) {
2028 float factor = start_factor;
2029 for (int frame = 0; frame < frameCount; ++frame) {
2030 if (factor >= 0.8) {
2031 break;
2032 }
2033 int pos = frame * channels;
2034 for (int ch = 0; ch < channels; ++ch) {
2035 values[pos + ch] = factor * values[pos + ch];
2036 }
2037 factor += inc;
2038 }
2039 start_factor = factor;
2040 }
2041
2042 void processEnd(T *values, int frameCount) {
2043 float factor = end_factor;
2044 for (int frame = frameCount - 1; frame >= 0; --frame) {
2045 if (factor >= 0.8) {
2046 break;
2047 }
2048 int pos = frame * channels;
2049 for (int ch = 0; ch < channels; ++ch) {
2050 values[pos + ch] = factor * values[pos + ch];
2051 }
2052 factor += inc;
2053 }
2054 end_factor = factor;
2055 }
2056};
2057
2064template <typename T, size_t Cn, size_t Cx, size_t S>
2066 public:
2067 CopyChannels() : _max_val(0), _counter(0), _prev_ms(0) {}
2068
2069 size_t convert(uint8_t *src, size_t size) {
2070 T *chan = (T *)src;
2071 size_t samples = (size / Cn) / sizeof(T);
2072 for (size_t s = 0; s < samples; s++) {
2073 chan[s * Cn + Cx] = (Cx < Cn) ? chan[s * Cn + Cx] << S : 0;
2074
2075 for (size_t c = 0; c < Cn; c++) {
2076 if (c != Cx) {
2077 chan[s * Cn + c] = chan[s * Cn + Cx];
2078 }
2079 }
2080
2081 if (_max_val < chan[s * Cn]) {
2082 _max_val = chan[s * Cn];
2083 }
2084
2085 _counter++;
2086 uint32_t now = millis();
2087 if (now - _prev_ms > 1000) {
2088 _prev_ms = now;
2089 LOGI("CopyChannels samples: %u, amplitude: %d", _counter, _max_val);
2090 _max_val = 0;
2091 }
2092 }
2093 return samples * Cn * sizeof(T);
2094 }
2095
2096 private:
2097 T _max_val;
2098 uint32_t _counter;
2099 uint32_t _prev_ms;
2100};
2101
2107template <typename T = int16_t>
2109 public:
2110 size_t convert(uint8_t *src, size_t size) override {
2111 T *data = (T *)src;
2112 int samples = size / sizeof(T);
2113 for (int j = 0; j < samples; j++) {
2114 data[j] = -data[j];
2115 }
2116 return size;
2117 }
2118};
2119
2125template <typename T = int16_t>
2127 public:
2129 CallbackConverterT(T (*callback)(T in, int channel), int channels = 2) {
2131 }
2132
2133 void setCallback(T (*callback)(T in, int channel), int channels) {
2134 this->callback = callback;
2135 this->channels = channels;
2136 }
2137
2138 size_t convert(uint8_t *src, size_t size) {
2139 // no conversion if no callback is provided
2140 if (callback == nullptr) {
2141 return size;
2142 }
2143 int samples = size / sizeof(T);
2144 T *srcT = (T *)src;
2145 for (int j = 0; j < samples; j++) {
2146 srcT[j] = callback(srcT[j], j % channels);
2147 }
2148 return size;
2149 }
2150
2151 protected:
2152 T (*callback)(T in, int channel) = nullptr;
2153 int channels = 2;
2154};
2155
2158
2159} // 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:27
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:906
int channels
Definition BaseConverter.h:1003
void setAverage(bool average)
Definition BaseConverter.h:929
~Bin() override
Definition BaseConverter.h:915
bool average
Definition BaseConverter.h:1006
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:940
void resetState()
Definition BaseConverter.h:998
Bin(int binSize, int channels, bool average, int bits_per_sample)
Definition BaseConverter.h:909
BinState * state
Definition BaseConverter.h:1007
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:941
void setChannels(int channels)
Definition BaseConverter.h:917
int binSize
Definition BaseConverter.h:1005
void clear()
Definition BaseConverter.h:933
int bits
Definition BaseConverter.h:1004
void reset()
Definition BaseConverter.h:938
void setBinSize(int binSize)
Definition BaseConverter.h:925
bool isConfigValid()
Definition BaseConverter.h:986
void setBits(int bits)
Definition BaseConverter.h:921
Definition BaseConverter.h:791
int channels
Definition BaseConverter.h:894
BinT(int binSize, int channels, bool average)
Definition BaseConverter.h:794
void setAverage(bool average)
Definition BaseConverter.h:811
bool average
Definition BaseConverter.h:896
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:815
~BinT()
Definition BaseConverter.h:801
void resetState()
Definition BaseConverter.h:883
SumT * partialBin
Definition BaseConverter.h:897
typename AppropriateSumType< T >::type SumT
Definition BaseConverter.h:863
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:817
void setChannels(int channels)
Definition BaseConverter.h:803
int binSize
Definition BaseConverter.h:895
void clear()
Definition BaseConverter.h:812
void reset()
Definition BaseConverter.h:813
int partialBinSize
Definition BaseConverter.h:898
void setBinSize(int binSize)
Definition BaseConverter.h:807
bool isConfigValid()
Definition BaseConverter.h:865
void resizeState()
Definition BaseConverter.h:877
You can provide a lambda expression to convert the data.
Definition BaseConverter.h:2126
int channels
Definition BaseConverter.h:2153
T(* callback)(T in, int channel)
Definition BaseConverter.h:2152
CallbackConverterT(T(*callback)(T in, int channel), int channels=2)
Definition BaseConverter.h:2129
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:2138
void setCallback(T(*callback)(T in, int channel), int channels)
Definition BaseConverter.h:2133
We average pairs of channels in a datastream. E.g. if we have 4 channels we end up with 2 channels....
Definition BaseConverter.h:1200
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1206
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1207
ChannelAvg(int bitsPerSample)
Definition BaseConverter.h:1203
int bits
Definition BaseConverter.h:1252
void setBits(int bits)
Definition BaseConverter.h:1204
We average pairs of channels in a datastream. E.g. if we have 4 channels we end up with 2 channels....
Definition BaseConverter.h:1152
ChannelAvgT()
Definition BaseConverter.h:1154
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:1156
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1160
Provides combination of binning and subtracting channels.
Definition BaseConverter.h:1389
int channels
Definition BaseConverter.h:1492
void setAverage(bool average)
Definition BaseConverter.h:1418
bool average
Definition BaseConverter.h:1495
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1429
void resetState()
Definition BaseConverter.h:1487
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1430
void setChannels(int channels)
Definition BaseConverter.h:1400
ChannelBinDiffState * state
Definition BaseConverter.h:1496
int binSize
Definition BaseConverter.h:1494
void clear()
Definition BaseConverter.h:1422
int bits
Definition BaseConverter.h:1493
void reset()
Definition BaseConverter.h:1427
~ChannelBinDiff() override
Definition BaseConverter.h:1398
void setBinSize(int binSize)
Definition BaseConverter.h:1414
bool isConfigValid()
Definition BaseConverter.h:1475
void setBits(int bits)
Definition BaseConverter.h:1410
ChannelBinDiff(int binSize, int channels, bool average, int bits_per_sample)
Definition BaseConverter.h:1392
We first bin the channels then we calculate the difference between pairs of channels in a datastream....
Definition BaseConverter.h:1269
int channels
Definition BaseConverter.h:1375
ChannelBinDiffT(int binSize, int channels, bool average)
Definition BaseConverter.h:1272
void setAverage(bool average)
Definition BaseConverter.h:1294
bool average
Definition BaseConverter.h:1377
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1298
void resetState()
Definition BaseConverter.h:1364
SumT * partialBin
Definition BaseConverter.h:1378
typename AppropriateSumType< T >::type SumT
Definition BaseConverter.h:1344
~ChannelBinDiffT()
Definition BaseConverter.h:1279
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1300
void setChannels(int channels)
Definition BaseConverter.h:1281
int binSize
Definition BaseConverter.h:1376
void clear()
Definition BaseConverter.h:1295
void reset()
Definition BaseConverter.h:1296
int partialBinSize
Definition BaseConverter.h:1379
void setBinSize(int binSize)
Definition BaseConverter.h:1290
bool isConfigValid()
Definition BaseConverter.h:1346
void resizeState()
Definition BaseConverter.h:1358
Increasing or decreasing the number of channels.
Definition BaseConverter.h:1561
void setTargetChannels(int channelCountOfTarget)
Definition BaseConverter.h:1574
ChannelReducerT< T > reducer
Definition BaseConverter.h:1602
int from_channels
Definition BaseConverter.h:1603
ChannelConverter(int channelCountOfTarget, int channelCountOfSource)
Definition BaseConverter.h:1565
ChannelEnhancer< T > enhancer
Definition BaseConverter.h:1601
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1578
int to_channels
Definition BaseConverter.h:1604
void setSourceChannels(int channelCountOfSource)
Definition BaseConverter.h:1570
Definition BaseConverter.h:1060
ChannelDiff(int bitsPerSample)
Definition BaseConverter.h:1063
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1066
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1067
int bits
Definition BaseConverter.h:1093
void setBits(int bits)
Definition BaseConverter.h:1064
We calculate the difference between pairs of channels in a datastream. E.g. if we have 4 channels we ...
Definition BaseConverter.h:1025
ChannelDiffT()
Definition BaseConverter.h:1027
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:1029
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1033
Increases the channel count.
Definition BaseConverter.h:1505
ChannelEnhancer(int channelCountOfTarget, int channelCountOfSource)
Definition BaseConverter.h:1509
void setTargetChannels(int channelCountOfTarget)
Definition BaseConverter.h:1518
size_t resultSize(size_t inSize)
Determine the size of the conversion result.
Definition BaseConverter.h:1546
int from_channels
Definition BaseConverter.h:1551
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:1522
int to_channels
Definition BaseConverter.h:1552
void setSourceChannels(int channelCountOfSource)
Definition BaseConverter.h:1514
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:1112
int channels
Definition BaseConverter.h:1135
ChannelMixer(int channels=2)
Definition BaseConverter.h:1114
size_t convert(uint8_t *data, size_t size)
Definition BaseConverter.h:1115
We combine a datastream which consists of multiple channels into less channels. E....
Definition BaseConverter.h:530
ChannelReducer(int channelCountOfTarget, int channelCountOfSource, int bitsPerSample)
Definition BaseConverter.h:532
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:539
int from_channels
Definition BaseConverter.h:564
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:541
int bits
Definition BaseConverter.h:566
int to_channels
Definition BaseConverter.h:565
We combine a datastream which consists of multiple channels into less channels. E....
Definition BaseConverter.h:474
ChannelReducerT(int channelCountOfTarget, int channelCountOfSource)
Definition BaseConverter.h:478
void setTargetChannels(int channelCountOfTarget)
Definition BaseConverter.h:487
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:491
int from_channels
Definition BaseConverter.h:520
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:493
int to_channels
Definition BaseConverter.h:521
void setSourceChannels(int channelCountOfSource)
Definition BaseConverter.h:483
Converter for 1 Channel which applies the indicated Filter.
Definition BaseConverter.h:1719
Converter1Channel(Filter< T > &filter)
Definition BaseConverter.h:1721
Filter< T > * p_filter
Definition BaseConverter.h:1732
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:1723
Makes sure that the avg of the signal is set to 0.
Definition BaseConverter.h:239
ConverterAutoCenter(int channels, int bitsPerSample)
Definition BaseConverter.h:247
BaseConverter * p_converter
Definition BaseConverter.h:312
int channels
Definition BaseConverter.h:309
bool is_dynamic
Definition BaseConverter.h:311
int bits_per_sample
Definition BaseConverter.h:310
bool begin(AudioInfo info, bool isDynamic=false)
Definition BaseConverter.h:259
ConverterAutoCenter(AudioInfo info)
Definition BaseConverter.h:243
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:295
void end()
Definition BaseConverter.h:252
bool begin(int channels, int bitsPerSample, bool isDynamic=false)
Definition BaseConverter.h:263
void clear()
Definition BaseConverter.h:300
void reset()
Definition BaseConverter.h:306
~ConverterAutoCenter()
Definition BaseConverter.h:250
Makes sure that the avg of the signal is set to 0.
Definition BaseConverter.h:132
int channels
Definition BaseConverter.h:185
Vector< acc_t > offset_to
Definition BaseConverter.h:177
Vector< acc_t > total
Definition BaseConverter.h:182
bool is_dynamic
Definition BaseConverter.h:184
float acc_t
Definition BaseConverter.h:174
ConverterAutoCenterT(int channels=2, bool isDynamic=false)
Definition BaseConverter.h:134
Vector< acc_t > offset_from
Definition BaseConverter.h:176
void resetState()
Definition BaseConverter.h:187
void setup(T *src, size_t size)
Definition BaseConverter.h:195
Vector< acc_t > dynamic_delta
Definition BaseConverter.h:181
bool is_setup
Definition BaseConverter.h:183
void clear()
Definition BaseConverter.h:139
void reset()
Definition BaseConverter.h:140
size_t convert(uint8_t(*src), size_t byte_count) override
Definition BaseConverter.h:142
Make sure that both channels contain any data. We copy the data from the non-empty channel to the emp...
Definition BaseConverter.h:363
size_t convert(uint8_t *src, size_t byte_count)
Definition BaseConverter.h:385
ConverterFillLeftAndRight(FillLeftAndRightStatus config=Auto, int channels=2)
Definition BaseConverter.h:365
Inverts the signal (multiplies every sample by -1)
Definition BaseConverter.h:2108
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:2110
Converter for n Channels which applies the indicated Filter.
Definition BaseConverter.h:1785
int getChannels()
Definition BaseConverter.h:1830
int channels
Definition BaseConverter.h:1847
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1814
Vector< Filter< FT > * > filters
Definition BaseConverter.h:1846
Filter< FT > * getFilter(int channel)
returns the filter for the indicated channel
Definition BaseConverter.h:1807
void setChannels(int newChannels)
Definition BaseConverter.h:1834
void setFilter(int channel, Filter< FT > *filter)
defines the filter for an individual channel - the first channel is 0
Definition BaseConverter.h:1797
ConverterNChannels(int channels)
Default Constructor.
Definition BaseConverter.h:1788
Multiplies the values with the indicated factor adds the offset and clips at maxValue....
Definition BaseConverter.h:58
void setFactor(float factor)
Defines the factor (volume)
Definition BaseConverter.h:98
int channels
Definition BaseConverter.h:115
acc_t factor_value
Definition BaseConverter.h:121
T offset_value
Definition BaseConverter.h:123
float acc_t
Definition BaseConverter.h:113
size_t convert(uint8_t *src, size_t byte_count)
Definition BaseConverter.h:67
T offset()
Determines the offset value.
Definition BaseConverter.h:107
ConverterScaler(float factor, T offset, T maxValue, int channels=2)
Definition BaseConverter.h:60
float factor()
Determines the actual factor (volume)
Definition BaseConverter.h:104
T maxValue
Definition BaseConverter.h:122
void setOffset(T offset)
Defines the offset.
Definition BaseConverter.h:101
Switches the left and right channel.
Definition BaseConverter.h:324
int channels
Definition BaseConverter.h:343
ConverterSwitchLeftAndRight(int channels=2)
Definition BaseConverter.h:326
size_t convert(uint8_t *src, size_t byte_count) override
Definition BaseConverter.h:328
special case for internal DAC output for the ESP32. The incomming PCM buffer needs to be converted fr...
Definition BaseConverter.h:446
int channels
Definition BaseConverter.h:463
ConverterToInternalDACFormat(int channels=2)
Definition BaseConverter.h:448
size_t convert(uint8_t *src, size_t byte_count) override
Definition BaseConverter.h:450
Copy channel Cx value of type T shifted by S bits to all Cn channels.
Definition BaseConverter.h:2065
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:2069
CopyChannels()
Definition BaseConverter.h:2067
Provides a reduced sampling rate by taking a sample at every factor location (ingoring factor-1 sampl...
Definition BaseConverter.h:654
DecimateState * state
Definition BaseConverter.h:751
int channels
Definition BaseConverter.h:748
void setFactor(int factor)
Sets the factor: e.g. with 4 we keep every forth sample.
Definition BaseConverter.h:672
int factor
Definition BaseConverter.h:750
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:684
void resetState()
Definition BaseConverter.h:743
Decimate(int factor, int channels, int bits_per_sample)
Definition BaseConverter.h:657
~Decimate() override
Definition BaseConverter.h:676
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:685
void setChannels(int channels)
Defines the number of channels.
Definition BaseConverter.h:663
void clear()
Definition BaseConverter.h:677
int bits
Definition BaseConverter.h:749
void reset()
Definition BaseConverter.h:682
bool isConfigValid()
Definition BaseConverter.h:731
void setBits(int bits)
Definition BaseConverter.h:667
Provides reduced sampling rates.
Definition BaseConverter.h:574
int channels
Definition BaseConverter.h:643
void setFactor(int factor)
Sets the factor: e.g. with 4 we keep every fourth sample.
Definition BaseConverter.h:589
int factor
Definition BaseConverter.h:644
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:596
void resetState()
Definition BaseConverter.h:641
size_t convert(uint8_t *target, uint8_t *src, size_t size)
Definition BaseConverter.h:598
void setChannels(int channels)
Defines the number of channels.
Definition BaseConverter.h:583
DecimateT(int factor, int channels)
Definition BaseConverter.h:576
void clear()
Definition BaseConverter.h:593
void reset()
Definition BaseConverter.h:594
bool isConfigValid()
Definition BaseConverter.h:629
uint16_t count
Definition BaseConverter.h:645
Abstract filter interface definition. Subclasses implement process() to transform audio samples one a...
Definition Filter.h:28
virtual T process(T in)=0
Processes the input value and returns the filtered output value.
Combines multiple converters.
Definition BaseConverter.h:1613
MultiConverter(BaseConverter &c1, BaseConverter &c2, BaseConverter &c3)
Definition BaseConverter.h:1624
MultiConverter(BaseConverter &c1)
Definition BaseConverter.h:1617
MultiConverter()
Definition BaseConverter.h:1615
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1634
MultiConverter(BaseConverter &c1, BaseConverter &c2)
Definition BaseConverter.h:1619
void add(BaseConverter &converter)
Definition BaseConverter.h:1631
Dummy converter which does nothing.
Definition BaseConverter.h:43
size_t convert(uint8_t(*src), size_t size) override
Definition BaseConverter.h:45
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:1649
NumberReader()
Definition BaseConverter.h:1653
NumberReader(Stream &in)
Definition BaseConverter.h:1651
int32_t scale(int32_t value, int inBits, int outBits, bool outSigned=true)
scale the value
Definition BaseConverter.h:1701
Stream * stream_ptr
Definition BaseConverter.h:1698
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:1668
bool read(int inBits, int outBits, bool outSigned, int n, int32_t *result)
Definition BaseConverter.h:1655
Big value gaps (at the beginning and the end of a recording) can lead to some popping sounds....
Definition BaseConverter.h:1938
int channels
Definition BaseConverter.h:1958
bool from_end
Definition BaseConverter.h:1957
void clearAfterLastTransition(int channels, int channel, T *values, int sampleCount)
Definition BaseConverter.h:1974
PoppingSoundRemover(int channels, bool fromBeginning, bool fromEnd)
Definition BaseConverter.h:1940
virtual size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:1945
void clearUpTo1stTransition(int channels, int channel, T *values, int sampleCount)
Definition BaseConverter.h:1960
bool from_beginning
Definition BaseConverter.h:1956
Removes any silence from the buffer that is longer then n samples with a amplitude below the indicate...
Definition BaseConverter.h:1860
bool active
Definition BaseConverter.h:1900
int priorLastAudioPos
Definition BaseConverter.h:1903
virtual size_t convert(uint8_t *data, size_t size) override
Definition BaseConverter.h:1869
int findLastAudioPos(T *audio, int pos)
Definition BaseConverter.h:1915
int n
Definition BaseConverter.h:1902
void clear()
Definition BaseConverter.h:1866
int amplidude_limit
Definition BaseConverter.h:1904
void reset()
Definition BaseConverter.h:1867
void set(int n=5, int aplidudeLimit=2)
Definition BaseConverter.h:1906
SilenceRemovalConverter(int n=8, int aplidudeLimit=2)
Definition BaseConverter.h:1862
const uint8_t * buffer
Definition BaseConverter.h:1901
Changes the samples at the beginning or at the end to slowly ramp up the volume.
Definition BaseConverter.h:1997
int channels
Definition BaseConverter.h:2022
void processStart(T *values, int frameCount)
Definition BaseConverter.h:2027
float inc
Definition BaseConverter.h:2023
bool from_end
Definition BaseConverter.h:2021
virtual size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:2011
float end_factor
Definition BaseConverter.h:2025
SmoothTransition(int channels, bool fromBeginning, bool fromEnd, float inc=0.01)
Definition BaseConverter.h:1999
float start_factor
Definition BaseConverter.h:2024
void clear()
Definition BaseConverter.h:2006
void processEnd(T *values, int frameCount)
Definition BaseConverter.h:2042
void reset()
Definition BaseConverter.h:2010
bool from_beginning
Definition BaseConverter.h:2020
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
Fixed-point Q1.14 number: a plain 16-bit signed integer holding 1 integer bit and 14 fractional bits ...
Definition q1_14_t.h:16
int32_t toInt32() const
converts to a 32-bit PCM sample (-2147483648..2147483647)
Definition q1_14_t.h:65
int24_t toInt24() const
converts to a 24-bit PCM sample (-8388608..8388607)
Definition q1_14_t.h:61
static q1_14_t fromInt16(int16_t sample)
builds a q1_14_t from a 16-bit PCM sample (-32768..32767)
Definition q1_14_t.h:70
int16_t toInt16() const
converts to a 16-bit PCM sample (-32768..32767)
Definition q1_14_t.h:57
static q1_14_t fromInt24(int24_t sample)
builds a q1_14_t from a 24-bit PCM sample (-8388608..8388607)
Definition q1_14_t.h:72
static q1_14_t fromInt32(int32_t sample)
builds a q1_14_t from a 32-bit PCM sample (-2147483648..2147483647)
Definition q1_14_t.h:76
Software "pseudo-float": a real number represented as a signed 16-bit mantissa plus a 16-bit exponent...
Definition soft_float_t.h:46
FillLeftAndRightStatus
Configure ConverterFillLeftAndRight.
Definition BaseConverter.h:350
@ LeftIsEmpty
Definition BaseConverter.h:350
@ RightIsEmpty
Definition BaseConverter.h:350
@ Auto
Definition BaseConverter.h:350
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
uint32_t millis()
Returns the milliseconds since the start.
Definition Arduino.h:260
int32_t type
Definition BaseConverter.h:777
int32_t type
Definition BaseConverter.h:782
int64_t type
Definition BaseConverter.h:787
int16_t type
Definition BaseConverter.h:772
We reduce the number of samples in a datastream by summing (binning) or averaging....
Definition BaseConverter.h:766
T type
Definition BaseConverter.h:767
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:966
virtual ~BinState()=default
virtual size_t convert(uint8_t *target, uint8_t *src, size_t size)=0
virtual void reset()=0
Definition BaseConverter.h:973
BinT< T > converter
Definition BaseConverter.h:983
size_t convert(uint8_t *target, uint8_t *src, size_t size) override
Definition BaseConverter.h:977
BinStateT(int binSize, int channels, bool average)
Definition BaseConverter.h:974
void reset() override
Definition BaseConverter.h:981
virtual size_t convert(uint8_t *target, uint8_t *src, size_t size)=0
ChannelBinDiffT< T > converter
Definition BaseConverter.h:1472
size_t convert(uint8_t *target, uint8_t *src, size_t size) override
Definition BaseConverter.h:1466
ChannelBinDiffStateT(int binSize, int channels, bool average)
Definition BaseConverter.h:1463
void reset() override
Definition BaseConverter.h:1470
Definition BaseConverter.h:712
virtual size_t convert(uint8_t *target, uint8_t *src, size_t size)=0
Definition BaseConverter.h:719
size_t convert(uint8_t *target, uint8_t *src, size_t size) override
Definition BaseConverter.h:722
DecimateStateT(int factor, int channels)
Definition BaseConverter.h:720
DecimateT< T > converter
Definition BaseConverter.h:728
void reset() override
Definition BaseConverter.h:726
static q1_14_t toFilterType(int16_t sample)
Definition BaseConverter.h:1756
static int16_t fromFilterType(q1_14_t value)
Definition BaseConverter.h:1759
static q1_14_t toFilterType(int24_t sample)
Definition BaseConverter.h:1764
static int24_t fromFilterType(q1_14_t value)
Definition BaseConverter.h:1767
static int32_t fromFilterType(q1_14_t value)
Definition BaseConverter.h:1775
static q1_14_t toFilterType(int32_t sample)
Definition BaseConverter.h:1772
Converts a raw sample (type T) to/from a filter's arithmetic type (FT) for ConverterNChannels....
Definition BaseConverter.h:1749
static T fromFilterType(FT value)
Definition BaseConverter.h:1751
static FT toFilterType(T sample)
Definition BaseConverter.h:1750