23 bool begin(
int fromChannels,
int toChannels) {
24 LOGI(
"begin %d -> %d channels", fromChannels, toChannels);
26 from_channels = fromChannels;
27 to_channels = toChannels;
28 factor =
static_cast<float>(toChannels) /
static_cast<float>(fromChannels);
30 converter.setSourceChannels(from_channels);
31 converter.setTargetChannels(to_channels);
36 bool begin()
override {
return begin(from_channels, to_channels); }
38 void setToChannels(uint16_t channels) { to_channels = channels; }
40 virtual size_t write(
const uint8_t *data,
size_t len)
override {
42 if (p_print ==
nullptr)
return 0;
44 if (from_channels == to_channels) {
45 return p_print->write(data, len);
47 size_t resultBytes = convert(data, len);
49 p_print->write((uint8_t *)buffer.data(), resultBytes);
53 size_t readBytes(uint8_t *data,
size_t len)
override {
55 if (p_stream ==
nullptr)
return 0;
56 if (from_channels == to_channels) {
57 return p_stream->readBytes(data, len);
59 size_t in_bytes = 1.0f / factor * len;
60 bufferTmp.resize(in_bytes);
61 p_stream->readBytes(bufferTmp.data(), in_bytes);
62 size_t resultBytes = convert(bufferTmp.data(), in_bytes);
63 assert(len == resultBytes);
64 memcpy(data, (uint8_t *)buffer.data(), len);
80 virtual int available()
override {
81 return p_stream !=
nullptr ? p_stream->available() : 0;
84 virtual int availableForWrite()
override {
85 if (p_print ==
nullptr)
return 0;
86 return 1.0f / factor * p_print->availableForWrite();
89 float getByteFactor()
override {
90 return static_cast<float>(to_channels) /
static_cast<float>(from_channels);
94 int from_channels = 2;
98 Vector<uint8_t> bufferTmp{0};
99 ChannelConverter<T> converter;
101 size_t convert(
const uint8_t *in_data,
size_t size) {
103 size_t result_samples = size /
sizeof(T) * factor;
104 buffer.resize(result_samples);
106 converter.convert((uint8_t *)buffer.data(), (uint8_t *)in_data, size);
107 if (result != result_samples *
sizeof(T)) {
108 LOGE(
"size %d -> result: %d - expeced: %d", (
int)size, (
int)result,
109 static_cast<int>(result_samples *
sizeof(T)));
134 begin(cfg, to_channels);
146 LOGE(
"invalid sample_rate: %d", (
int)to.
sample_rate);
156 bool begin(AudioInfo cfg,
int toChannels) {
158 if (toChannels == 0) {
159 LOGE(
"toChannels is 0");
163 to_channels = toChannels;
164 from_channels = cfg.channels;
165 bits_per_sample = cfg.bits_per_sample;
166 LOGI(
"--> ChannelFormatConverterStream");
168 LOGI(
"begin %d -> %d channels", cfg.channels, toChannels);
169 is_active = setupConverter(cfg.channels, toChannels);
176 bool begin()
override {
return begin(
audioInfo(), to_channels); }
178 void end()
override {
183 void setToChannels(uint16_t channels) { to_channels = channels; }
185 virtual size_t write(
const uint8_t *data,
size_t len)
override {
186 LOGD(
"ChannelFormatConverterStream::write: %d", (
int)len);
187 if (p_print ==
nullptr)
return 0;
189 switch (bits_per_sample) {
191 return getConverter<int8_t>()->write(data, len);
193 return getConverter<int16_t>()->write(data, len);
195 return getConverter<int24_t>()->write(data, len);
197 return getConverter<int32_t>()->write(data, len);
203 size_t readBytes(uint8_t *data,
size_t len)
override {
204 LOGD(
"ChannelFormatConverterStream::readBytes: %d", (
int)len);
205 switch (bits_per_sample) {
207 return getConverter<int8_t>()->readBytes(data, len);
209 return getConverter<int16_t>()->readBytes(data, len);
211 return getConverter<int24_t>()->readBytes(data, len);
213 return getConverter<int32_t>()->readBytes(data, len);
219 virtual int available()
override {
220 switch (bits_per_sample) {
222 return getConverter<int8_t>()->available();
224 return getConverter<int16_t>()->available();
226 return getConverter<int24_t>()->available();
228 return getConverter<int32_t>()->available();
234 virtual int availableForWrite()
override {
235 switch (bits_per_sample) {
237 return getConverter<int8_t>()->availableForWrite();
239 return getConverter<int16_t>()->availableForWrite();
241 return getConverter<int24_t>()->availableForWrite();
243 return getConverter<int32_t>()->availableForWrite();
249 float getByteFactor()
override {
250 return static_cast<float>(to_channels) /
static_cast<float>(from_channels);
254 void *converter =
nullptr;
255 int bits_per_sample = 0;
257 int from_channels = 0;
258 bool is_active =
false;
260 template <
typename T>
261 ChannelFormatConverterStreamT<T> *getConverter() {
262 return (ChannelFormatConverterStreamT<T> *)converter;
265 void cleanupConverter() {
266 if (converter ==
nullptr)
return;
267 switch (bits_per_sample) {
269 delete getConverter<int8_t>();
273 delete getConverter<int16_t>();
277 delete getConverter<int24_t>();
281 delete getConverter<int32_t>();
287 bool setupConverter(
int fromChannels,
int toChannels) {
290 switch (bits_per_sample) {
292 converter =
new ChannelFormatConverterStreamT<int8_t>(*p_stream);
293 getConverter<int8_t>()->begin(fromChannels, toChannels);
296 converter =
new ChannelFormatConverterStreamT<int16_t>(*p_stream);
297 getConverter<int16_t>()->begin(fromChannels, toChannels);
300 converter =
new ChannelFormatConverterStreamT<int24_t>(*p_stream);
301 getConverter<int24_t>()->begin(fromChannels, toChannels);
304 converter =
new ChannelFormatConverterStreamT<int32_t>(*p_stream);
305 getConverter<int32_t>()->begin(fromChannels, toChannels);
458 LOGI(
"-> NumberFormatConverterStream:")
470 LOGE(
"sample_rate does not match")
473 if (info.channels != to.channels) {
474 LOGE(
"channels do not match")
477 return begin(info, to.bits_per_sample, gain);
480 bool begin(
AudioInfo info,
int toBits,
float gain = 1.0f) {
482 return begin(info.bits_per_sample, toBits, gain);
485 bool begin()
override {
486 return begin(from_bit_per_samples, to_bit_per_samples, gain);
489 void end()
override { cleanupConverter(); }
491 void setToBits(uint8_t bits) { to_bit_per_samples = bits; }
493 bool begin(
int from_bit_per_samples,
int to_bit_per_samples,
495 LOGI(
"begin %d -> %d bits", from_bit_per_samples, to_bit_per_samples);
497 assert(to_bit_per_samples > 0);
500 if (p_converter !=
nullptr) end();
504 this->from_bit_per_samples = from_bit_per_samples;
505 this->to_bit_per_samples = to_bit_per_samples;
507 if (from_bit_per_samples == to_bit_per_samples) {
508 LOGI(
"no bit conversion: %d -> %d", from_bit_per_samples,
510 }
else if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
512 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
514 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
516 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
518 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
520 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
524 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
528 if (from_bit_per_samples != to_bit_per_samples) {
538 virtual size_t write(
const uint8_t *data,
size_t len)
override {
539 LOGD(
"NumberFormatConverterStream::write: %d", (
int)len);
540 if (p_print ==
nullptr)
return 0;
541 if (from_bit_per_samples == to_bit_per_samples) {
542 return p_print->write(data, len);
545 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
546 return getConverter<int8_t, int16_t>()->write(data, len);
547 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
548 return getConverter<int16_t, int8_t>()->write(data, len);
549 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
550 return getConverter<int24_t, int16_t>()->write(data, len);
551 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
552 return getConverter<int16_t, int24_t>()->write(data, len);
553 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
554 return getConverter<int32_t, int16_t>()->write(data, len);
555 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
556 return getConverter<int16_t, int32_t>()->write(data, len);
558 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
564 size_t readBytes(uint8_t *data,
size_t len)
override {
565 LOGD(
"NumberFormatConverterStream::readBytes: %d", (
int)len);
566 if (from_bit_per_samples == to_bit_per_samples) {
567 return p_stream->readBytes(data, len);
569 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
570 return getConverter<int8_t, int16_t>()->readBytes(data, len);
571 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
572 return getConverter<int16_t, int8_t>()->readBytes(data, len);
573 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
574 return getConverter<int24_t, int16_t>()->readBytes(data, len);
575 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
576 return getConverter<int16_t, int24_t>()->readBytes(data, len);
577 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
578 return getConverter<int32_t, int16_t>()->readBytes(data, len);
579 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
580 return getConverter<int16_t, int32_t>()->readBytes(data, len);
587 virtual int available()
override {
588 if (from_bit_per_samples == to_bit_per_samples) {
589 return p_stream->available();
591 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
592 return getConverter<int8_t, int16_t>()->available();
593 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
594 return getConverter<int16_t, int8_t>()->available();
595 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
596 return getConverter<int24_t, int16_t>()->available();
597 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
598 return getConverter<int16_t, int24_t>()->available();
599 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
600 return getConverter<int32_t, int16_t>()->available();
601 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
602 return getConverter<int16_t, int32_t>()->available();
609 virtual int availableForWrite()
override {
610 if (p_print ==
nullptr)
return 0;
611 if (from_bit_per_samples == to_bit_per_samples) {
612 return p_print->availableForWrite();
614 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
615 return getConverter<int8_t, int16_t>()->availableForWrite();
616 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
617 return getConverter<int16_t, int8_t>()->availableForWrite();
618 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
619 return getConverter<int24_t, int16_t>()->availableForWrite();
620 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
621 return getConverter<int16_t, int24_t>()->availableForWrite();
622 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
623 return getConverter<int32_t, int16_t>()->availableForWrite();
624 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
625 return getConverter<int16_t, int32_t>()->availableForWrite();
632 void setBuffered(
bool flag) {
633 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
634 getConverter<int8_t, int16_t>()->setBuffered(flag);
635 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
636 getConverter<int16_t, int8_t>()->setBuffered(flag);
637 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
638 getConverter<int24_t, int16_t>()->setBuffered(flag);
639 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
640 getConverter<int16_t, int24_t>()->setBuffered(flag);
641 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
642 getConverter<int32_t, int16_t>()->setBuffered(flag);
643 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
644 getConverter<int16_t, int32_t>()->setBuffered(flag);
648 float getByteFactor()
override {
649 return static_cast<float>(to_bit_per_samples) /
650 static_cast<float>(from_bit_per_samples);
654 void *p_converter =
nullptr;
655 int from_bit_per_samples = 16;
656 int to_bit_per_samples = 0;
659 void cleanupConverter() {
660 if (p_converter ==
nullptr)
return;
662 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
663 delete static_cast<NumberFormatConverterStreamT<int8_t, int16_t> *
>(
665 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
666 delete static_cast<NumberFormatConverterStreamT<int16_t, int8_t> *
>(
668 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
669 delete static_cast<NumberFormatConverterStreamT<int24_t, int16_t> *
>(
671 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
672 delete static_cast<NumberFormatConverterStreamT<int16_t, int24_t> *
>(
674 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
675 delete static_cast<NumberFormatConverterStreamT<int32_t, int16_t> *
>(
677 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
678 delete static_cast<NumberFormatConverterStreamT<int16_t, int32_t> *
>(
683 p_converter =
nullptr;
686 template <
typename TFrom,
typename TTo>
687 NumberFormatConverterStreamT<TFrom, TTo> *getConverter() {
688 return (NumberFormatConverterStreamT<TFrom, TTo> *)p_converter;
692 if (p_stream !=
nullptr) {
693 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
694 getConverter<int8_t, int16_t>()->setStream(*p_stream);
695 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
696 getConverter<int16_t, int8_t>()->setStream(*p_stream);
697 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
698 getConverter<int24_t, int16_t>()->setStream(*p_stream);
699 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
700 getConverter<int16_t, int24_t>()->setStream(*p_stream);
701 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
702 getConverter<int32_t, int16_t>()->setStream(*p_stream);
703 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
704 getConverter<int16_t, int32_t>()->setStream(*p_stream);
709 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
710 getConverter<int8_t, int16_t>()->setOutput(*p_print);
711 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
712 getConverter<int16_t, int8_t>()->setOutput(*p_print);
713 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
714 getConverter<int24_t, int16_t>()->setOutput(*p_print);
715 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
716 getConverter<int16_t, int24_t>()->setOutput(*p_print);
717 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
718 getConverter<int32_t, int16_t>()->setOutput(*p_print);
719 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
720 getConverter<int16_t, int32_t>()->setOutput(*p_print);