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)));
136 begin(cfg, to_channels);
148 LOGE(
"invalid sample_rate: %d", (
int)to.
sample_rate);
158 bool begin(AudioInfo cfg,
int toChannels) {
160 if (toChannels == 0) {
161 LOGE(
"toChannels is 0");
165 to_channels = toChannels;
166 from_channels = cfg.channels;
167 bits_per_sample = cfg.bits_per_sample;
168 LOGI(
"--> ChannelFormatConverterStream");
170 LOGI(
"begin %d -> %d channels", cfg.channels, toChannels);
171 is_active = setupConverter(cfg.channels, toChannels);
178 bool begin()
override {
return begin(
audioInfo(), to_channels); }
180 void end()
override {
185 void setToChannels(uint16_t channels) { to_channels = channels; }
187 virtual size_t write(
const uint8_t *data,
size_t len)
override {
188 LOGD(
"ChannelFormatConverterStream::write: %d", (
int)len);
189 if (p_print ==
nullptr)
return 0;
191 switch (bits_per_sample) {
193 return getConverter<int8_t>()->write(data, len);
195 return getConverter<int16_t>()->write(data, len);
197 return getConverter<int24_t>()->write(data, len);
199 return getConverter<int32_t>()->write(data, len);
205 size_t readBytes(uint8_t *data,
size_t len)
override {
206 LOGD(
"ChannelFormatConverterStream::readBytes: %d", (
int)len);
207 switch (bits_per_sample) {
209 return getConverter<int8_t>()->readBytes(data, len);
211 return getConverter<int16_t>()->readBytes(data, len);
213 return getConverter<int24_t>()->readBytes(data, len);
215 return getConverter<int32_t>()->readBytes(data, len);
221 virtual int available()
override {
222 switch (bits_per_sample) {
224 return getConverter<int8_t>()->available();
226 return getConverter<int16_t>()->available();
228 return getConverter<int24_t>()->available();
230 return getConverter<int32_t>()->available();
236 virtual int availableForWrite()
override {
237 switch (bits_per_sample) {
239 return getConverter<int8_t>()->availableForWrite();
241 return getConverter<int16_t>()->availableForWrite();
243 return getConverter<int24_t>()->availableForWrite();
245 return getConverter<int32_t>()->availableForWrite();
251 float getByteFactor()
override {
252 return static_cast<float>(to_channels) /
static_cast<float>(from_channels);
256 void *converter =
nullptr;
257 int bits_per_sample = 0;
259 int from_channels = 0;
260 bool is_active =
false;
262 void copy(ChannelFormatConverterStream &from) {
264 if (from.converter !=
nullptr) {
265 setupConverter(from.from_channels, from.to_channels);
267 bits_per_sample = from.bits_per_sample;
268 to_channels = from.to_channels;
269 from_channels = from.from_channels;
270 is_active = from.is_active;
273 template <
typename T>
274 ChannelFormatConverterStreamT<T> *getConverter() {
275 return (ChannelFormatConverterStreamT<T> *)converter;
278 void cleanupConverter() {
279 if (converter ==
nullptr)
return;
280 switch (bits_per_sample) {
282 delete getConverter<int8_t>();
286 delete getConverter<int16_t>();
290 delete getConverter<int24_t>();
294 delete getConverter<int32_t>();
300 bool setupConverter(
int fromChannels,
int toChannels) {
303 switch (bits_per_sample) {
305 converter =
new ChannelFormatConverterStreamT<int8_t>(*p_stream);
306 getConverter<int8_t>()->begin(fromChannels, toChannels);
309 converter =
new ChannelFormatConverterStreamT<int16_t>(*p_stream);
310 getConverter<int16_t>()->begin(fromChannels, toChannels);
313 converter =
new ChannelFormatConverterStreamT<int24_t>(*p_stream);
314 getConverter<int24_t>()->begin(fromChannels, toChannels);
317 converter =
new ChannelFormatConverterStreamT<int32_t>(*p_stream);
318 getConverter<int32_t>()->begin(fromChannels, toChannels);
471 LOGI(
"-> NumberFormatConverterStream:")
483 LOGE(
"sample_rate does not match")
486 if (info.channels != to.channels) {
487 LOGE(
"channels do not match")
490 return begin(info, to.bits_per_sample, gain);
493 bool begin(
AudioInfo info,
int toBits,
float gain = 1.0f) {
495 return begin(info.bits_per_sample, toBits, gain);
498 bool begin()
override {
499 return begin(from_bit_per_samples, to_bit_per_samples, gain);
502 void end()
override { cleanupConverter(); }
504 void setToBits(uint8_t bits) { to_bit_per_samples = bits; }
506 bool begin(
int from_bit_per_samples,
int to_bit_per_samples,
508 LOGI(
"begin %d -> %d bits", from_bit_per_samples, to_bit_per_samples);
510 assert(to_bit_per_samples > 0);
513 if (p_converter !=
nullptr) end();
517 this->from_bit_per_samples = from_bit_per_samples;
518 this->to_bit_per_samples = to_bit_per_samples;
520 if (from_bit_per_samples == to_bit_per_samples) {
521 LOGI(
"no bit conversion: %d -> %d", from_bit_per_samples,
523 }
else if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
525 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
527 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
529 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
531 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
533 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
537 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
541 if (from_bit_per_samples != to_bit_per_samples) {
551 virtual size_t write(
const uint8_t *data,
size_t len)
override {
552 LOGD(
"NumberFormatConverterStream::write: %d", (
int)len);
553 if (p_print ==
nullptr)
return 0;
554 if (from_bit_per_samples == to_bit_per_samples) {
555 return p_print->write(data, len);
558 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
559 return getConverter<int8_t, int16_t>()->write(data, len);
560 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
561 return getConverter<int16_t, int8_t>()->write(data, len);
562 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
563 return getConverter<int24_t, int16_t>()->write(data, len);
564 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
565 return getConverter<int16_t, int24_t>()->write(data, len);
566 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
567 return getConverter<int32_t, int16_t>()->write(data, len);
568 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
569 return getConverter<int16_t, int32_t>()->write(data, len);
571 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
577 size_t readBytes(uint8_t *data,
size_t len)
override {
578 LOGD(
"NumberFormatConverterStream::readBytes: %d", (
int)len);
579 if (from_bit_per_samples == to_bit_per_samples) {
580 return p_stream->readBytes(data, len);
582 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
583 return getConverter<int8_t, int16_t>()->readBytes(data, len);
584 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
585 return getConverter<int16_t, int8_t>()->readBytes(data, len);
586 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
587 return getConverter<int24_t, int16_t>()->readBytes(data, len);
588 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
589 return getConverter<int16_t, int24_t>()->readBytes(data, len);
590 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
591 return getConverter<int32_t, int16_t>()->readBytes(data, len);
592 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
593 return getConverter<int16_t, int32_t>()->readBytes(data, len);
600 virtual int available()
override {
601 if (from_bit_per_samples == to_bit_per_samples) {
602 return p_stream->available();
604 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
605 return getConverter<int8_t, int16_t>()->available();
606 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
607 return getConverter<int16_t, int8_t>()->available();
608 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
609 return getConverter<int24_t, int16_t>()->available();
610 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
611 return getConverter<int16_t, int24_t>()->available();
612 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
613 return getConverter<int32_t, int16_t>()->available();
614 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
615 return getConverter<int16_t, int32_t>()->available();
622 virtual int availableForWrite()
override {
623 if (p_print ==
nullptr)
return 0;
624 if (from_bit_per_samples == to_bit_per_samples) {
625 return p_print->availableForWrite();
627 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
628 return getConverter<int8_t, int16_t>()->availableForWrite();
629 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
630 return getConverter<int16_t, int8_t>()->availableForWrite();
631 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
632 return getConverter<int24_t, int16_t>()->availableForWrite();
633 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
634 return getConverter<int16_t, int24_t>()->availableForWrite();
635 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
636 return getConverter<int32_t, int16_t>()->availableForWrite();
637 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
638 return getConverter<int16_t, int32_t>()->availableForWrite();
645 void setBuffered(
bool flag) {
646 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
647 getConverter<int8_t, int16_t>()->setBuffered(flag);
648 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
649 getConverter<int16_t, int8_t>()->setBuffered(flag);
650 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
651 getConverter<int24_t, int16_t>()->setBuffered(flag);
652 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
653 getConverter<int16_t, int24_t>()->setBuffered(flag);
654 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
655 getConverter<int32_t, int16_t>()->setBuffered(flag);
656 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
657 getConverter<int16_t, int32_t>()->setBuffered(flag);
661 float getByteFactor()
override {
662 return static_cast<float>(to_bit_per_samples) /
663 static_cast<float>(from_bit_per_samples);
667 void *p_converter =
nullptr;
668 int from_bit_per_samples = 16;
669 int to_bit_per_samples = 0;
672 void cleanupConverter() {
673 if (p_converter ==
nullptr)
return;
675 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
676 delete static_cast<NumberFormatConverterStreamT<int8_t, int16_t> *
>(
678 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
679 delete static_cast<NumberFormatConverterStreamT<int16_t, int8_t> *
>(
681 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
682 delete static_cast<NumberFormatConverterStreamT<int24_t, int16_t> *
>(
684 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
685 delete static_cast<NumberFormatConverterStreamT<int16_t, int24_t> *
>(
687 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
688 delete static_cast<NumberFormatConverterStreamT<int32_t, int16_t> *
>(
690 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
691 delete static_cast<NumberFormatConverterStreamT<int16_t, int32_t> *
>(
696 p_converter =
nullptr;
699 template <
typename TFrom,
typename TTo>
700 NumberFormatConverterStreamT<TFrom, TTo> *getConverter() {
701 return (NumberFormatConverterStreamT<TFrom, TTo> *)p_converter;
705 if (p_stream !=
nullptr) {
706 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
707 getConverter<int8_t, int16_t>()->setStream(*p_stream);
708 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
709 getConverter<int16_t, int8_t>()->setStream(*p_stream);
710 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
711 getConverter<int24_t, int16_t>()->setStream(*p_stream);
712 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
713 getConverter<int16_t, int24_t>()->setStream(*p_stream);
714 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
715 getConverter<int32_t, int16_t>()->setStream(*p_stream);
716 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
717 getConverter<int16_t, int32_t>()->setStream(*p_stream);
722 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
723 getConverter<int8_t, int16_t>()->setOutput(*p_print);
724 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
725 getConverter<int16_t, int8_t>()->setOutput(*p_print);
726 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
727 getConverter<int24_t, int16_t>()->setOutput(*p_print);
728 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
729 getConverter<int16_t, int24_t>()->setOutput(*p_print);
730 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
731 getConverter<int32_t, int16_t>()->setOutput(*p_print);
732 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
733 getConverter<int16_t, int32_t>()->setOutput(*p_print);