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)));
139 begin(cfg, to_channels);
155 LOGE(
"invalid sample_rate: %d", (
int)to.
sample_rate);
165 bool begin(AudioInfo cfg,
int toChannels) {
167 if (toChannels == 0) {
168 LOGE(
"toChannels is 0");
172 to_channels = toChannels;
173 from_channels = cfg.channels;
174 bits_per_sample = cfg.bits_per_sample;
175 LOGI(
"--> ChannelFormatConverterStream");
177 LOGI(
"begin %d -> %d channels", cfg.channels, toChannels);
178 is_active = setupConverter(cfg.channels, toChannels);
185 bool begin()
override {
return begin(
audioInfo(), to_channels); }
187 void end()
override {
192 void setToChannels(uint16_t channels) { to_channels = channels; }
194 virtual size_t write(
const uint8_t* data,
size_t len)
override {
195 LOGD(
"ChannelFormatConverterStream::write: %d", (
int)len);
196 if (p_print ==
nullptr)
return 0;
198 switch (bits_per_sample) {
200 return getConverter<int8_t>()->write(data, len);
202 return getConverter<int16_t>()->write(data, len);
204 return getConverter<int24_t>()->write(data, len);
206 return getConverter<int32_t>()->write(data, len);
212 size_t readBytes(uint8_t* data,
size_t len)
override {
213 LOGD(
"ChannelFormatConverterStream::readBytes: %d", (
int)len);
214 switch (bits_per_sample) {
216 return getConverter<int8_t>()->readBytes(data, len);
218 return getConverter<int16_t>()->readBytes(data, len);
220 return getConverter<int24_t>()->readBytes(data, len);
222 return getConverter<int32_t>()->readBytes(data, len);
228 virtual int available()
override {
229 switch (bits_per_sample) {
231 return getConverter<int8_t>()->available();
233 return getConverter<int16_t>()->available();
235 return getConverter<int24_t>()->available();
237 return getConverter<int32_t>()->available();
243 virtual int availableForWrite()
override {
244 switch (bits_per_sample) {
246 return getConverter<int8_t>()->availableForWrite();
248 return getConverter<int16_t>()->availableForWrite();
250 return getConverter<int24_t>()->availableForWrite();
252 return getConverter<int32_t>()->availableForWrite();
258 float getByteFactor()
override {
259 return static_cast<float>(to_channels) /
static_cast<float>(from_channels);
263 void* converter =
nullptr;
264 int bits_per_sample = 0;
266 int from_channels = 2;
267 bool is_active =
false;
269 void copy(ChannelFormatConverterStream& from) {
271 if (from.converter !=
nullptr) {
272 setupConverter(from.from_channels, from.to_channels);
274 bits_per_sample = from.bits_per_sample;
275 to_channels = from.to_channels;
276 from_channels = from.from_channels;
277 is_active = from.is_active;
280 template <
typename T>
281 ChannelFormatConverterStreamT<T>* getConverter() {
282 return (ChannelFormatConverterStreamT<T>*)converter;
285 void cleanupConverter() {
286 if (converter ==
nullptr)
return;
287 switch (bits_per_sample) {
289 delete getConverter<int8_t>();
293 delete getConverter<int16_t>();
297 delete getConverter<int24_t>();
301 delete getConverter<int32_t>();
307 bool setupConverter(
int fromChannels,
int toChannels) {
310 switch (bits_per_sample) {
312 converter =
new ChannelFormatConverterStreamT<int8_t>(*p_stream);
313 getConverter<int8_t>()->begin(fromChannels, toChannels);
316 converter =
new ChannelFormatConverterStreamT<int16_t>(*p_stream);
317 getConverter<int16_t>()->begin(fromChannels, toChannels);
320 converter =
new ChannelFormatConverterStreamT<int24_t>(*p_stream);
321 getConverter<int24_t>()->begin(fromChannels, toChannels);
324 converter =
new ChannelFormatConverterStreamT<int32_t>(*p_stream);
325 getConverter<int32_t>()->begin(fromChannels, toChannels);
360 LOGW(
"Inconsistent source bits_per_sample %d, using %d", newInfo.
bits_per_sample, (
int)
sizeof(TFrom) * 8);
372 bool begin()
override {
373 LOGI(
"begin %d -> %d bits", (
int)
sizeof(TFrom)*8, (
int)
sizeof(TTo)*8);
378 bool begin(AudioInfo info){
383 virtual size_t write(
const uint8_t* data,
size_t len)
override {
385 if (p_print ==
nullptr)
return 0;
389 if (std::is_same<TFrom, TTo>::value)
return p_print->write(data, len);
391 if (
sizeof(TFrom) ==
sizeof(TTo))
return p_print->write(data, len);
394 size_t samples = len /
sizeof(TFrom);
395 size_t result_size = 0;
396 TFrom* data_source = (TFrom*)data;
399 for (
size_t j = 0; j < samples; j++) {
400 TTo value = NumberConverter::convert<TFrom, TTo>(data_source[j]);
401 result_size += p_print->write((uint8_t*)&value,
sizeof(TTo));
404 int size_bytes =
sizeof(TTo) * samples;
405 buffer.
resize(size_bytes);
406 NumberConverter::convertArray<TFrom, TTo>(
407 data_source, (TTo*)buffer.
data(), samples, gain);
408 result_size = p_print->write((uint8_t*)buffer.
address(), size_bytes);
412 return result_size > 0 ? len : 0;
415 size_t readBytes(uint8_t* data,
size_t len)
override {
416 LOGD(
"NumberFormatConverterStreamT::readBytes: %d", (
int)len);
417 if (p_stream ==
nullptr)
return 0;
418 size_t samples = len /
sizeof(TTo);
419 TTo* data_target = (TTo*)data;
422 for (
size_t j = 0; j < samples; j++) {
424 p_stream->readBytes((uint8_t*)&source,
sizeof(TFrom));
425 data_target[j] = NumberConverter::convert<TFrom, TTo>(source);
428 buffer.
resize(
sizeof(TFrom) * samples);
429 readSamples<TFrom>(p_stream, (TFrom*)buffer.
address(), samples);
430 TFrom* data = (TFrom*)buffer.
address();
431 NumberConverter::convertArray<TFrom, TTo>(data, data_target, samples,
438 virtual int available()
override {
439 return p_stream !=
nullptr ? p_stream->available() : 0;
442 virtual int availableForWrite()
override {
443 return p_print ==
nullptr ? 0 : p_print->availableForWrite();
453 float getByteFactor()
override {
454 return static_cast<float>(
sizeof(TTo)) /
static_cast<float>(
sizeof(TFrom));
458 SingleBuffer<uint8_t> buffer{0};
459 bool is_buffered =
true;
483 LOGI(
"-> NumberFormatConverterStream:")
495 LOGE(
"sample_rate does not match")
498 if (info.channels != to.channels) {
499 LOGE(
"channels do not match")
502 return begin(info, to.bits_per_sample, gain);
505 bool begin(
AudioInfo info,
int toBits,
float gain = 1.0f) {
507 return begin(info.bits_per_sample, toBits, gain);
510 bool begin()
override {
511 return begin(from_bit_per_samples, to_bit_per_samples, gain);
514 void end()
override { cleanupConverter(); }
516 void setToBits(uint8_t bits) { to_bit_per_samples = bits; }
518 bool begin(
int from_bit_per_samples,
int to_bit_per_samples,
520 LOGI(
"begin %d -> %d bits", from_bit_per_samples, to_bit_per_samples);
522 assert(to_bit_per_samples > 0);
525 if (p_converter !=
nullptr) end();
529 this->from_bit_per_samples = from_bit_per_samples;
530 this->to_bit_per_samples = to_bit_per_samples;
532 if (from_bit_per_samples == to_bit_per_samples) {
533 LOGI(
"no bit conversion: %d -> %d", from_bit_per_samples,
535 }
else if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
537 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
539 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
541 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
543 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
545 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
549 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
553 if (from_bit_per_samples != to_bit_per_samples) {
563 virtual size_t write(
const uint8_t* data,
size_t len)
override {
564 LOGD(
"NumberFormatConverterStream::write: %d", (
int)len);
565 if (p_print ==
nullptr)
return 0;
566 if (from_bit_per_samples == to_bit_per_samples) {
567 return p_print->write(data, len);
570 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
571 return getConverter<int8_t, int16_t>()->write(data, len);
572 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
573 return getConverter<int16_t, int8_t>()->write(data, len);
574 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
575 return getConverter<int24_t, int16_t>()->write(data, len);
576 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
577 return getConverter<int16_t, int24_t>()->write(data, len);
578 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
579 return getConverter<int32_t, int16_t>()->write(data, len);
580 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
581 return getConverter<int16_t, int32_t>()->write(data, len);
583 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
589 size_t readBytes(uint8_t* data,
size_t len)
override {
590 LOGD(
"NumberFormatConverterStream::readBytes: %d", (
int)len);
591 if (from_bit_per_samples == to_bit_per_samples) {
592 return p_stream->readBytes(data, len);
594 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
595 return getConverter<int8_t, int16_t>()->readBytes(data, len);
596 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
597 return getConverter<int16_t, int8_t>()->readBytes(data, len);
598 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
599 return getConverter<int24_t, int16_t>()->readBytes(data, len);
600 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
601 return getConverter<int16_t, int24_t>()->readBytes(data, len);
602 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
603 return getConverter<int32_t, int16_t>()->readBytes(data, len);
604 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
605 return getConverter<int16_t, int32_t>()->readBytes(data, len);
612 virtual int available()
override {
613 if (from_bit_per_samples == to_bit_per_samples) {
614 return p_stream->available();
616 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
617 return getConverter<int8_t, int16_t>()->available();
618 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
619 return getConverter<int16_t, int8_t>()->available();
620 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
621 return getConverter<int24_t, int16_t>()->available();
622 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
623 return getConverter<int16_t, int24_t>()->available();
624 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
625 return getConverter<int32_t, int16_t>()->available();
626 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
627 return getConverter<int16_t, int32_t>()->available();
634 virtual int availableForWrite()
override {
635 if (p_print ==
nullptr)
return 0;
636 if (from_bit_per_samples == to_bit_per_samples) {
637 return p_print->availableForWrite();
639 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
640 return getConverter<int8_t, int16_t>()->availableForWrite();
641 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
642 return getConverter<int16_t, int8_t>()->availableForWrite();
643 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
644 return getConverter<int24_t, int16_t>()->availableForWrite();
645 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
646 return getConverter<int16_t, int24_t>()->availableForWrite();
647 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
648 return getConverter<int32_t, int16_t>()->availableForWrite();
649 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
650 return getConverter<int16_t, int32_t>()->availableForWrite();
657 void setBuffered(
bool flag) {
658 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
659 getConverter<int8_t, int16_t>()->setBuffered(flag);
660 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
661 getConverter<int16_t, int8_t>()->setBuffered(flag);
662 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
663 getConverter<int24_t, int16_t>()->setBuffered(flag);
664 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
665 getConverter<int16_t, int24_t>()->setBuffered(flag);
666 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
667 getConverter<int32_t, int16_t>()->setBuffered(flag);
668 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
669 getConverter<int16_t, int32_t>()->setBuffered(flag);
673 float getByteFactor()
override {
674 return static_cast<float>(to_bit_per_samples) /
675 static_cast<float>(from_bit_per_samples);
679 void* p_converter =
nullptr;
680 int from_bit_per_samples = 16;
681 int to_bit_per_samples = 0;
684 void cleanupConverter() {
685 if (p_converter ==
nullptr)
return;
687 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
688 delete static_cast<NumberFormatConverterStreamT<int8_t, int16_t>*
>(
690 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
691 delete static_cast<NumberFormatConverterStreamT<int16_t, int8_t>*
>(
693 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
694 delete static_cast<NumberFormatConverterStreamT<int24_t, int16_t>*
>(
696 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
697 delete static_cast<NumberFormatConverterStreamT<int16_t, int24_t>*
>(
699 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
700 delete static_cast<NumberFormatConverterStreamT<int32_t, int16_t>*
>(
702 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
703 delete static_cast<NumberFormatConverterStreamT<int16_t, int32_t>*
>(
708 p_converter =
nullptr;
711 template <
typename TFrom,
typename TTo>
712 NumberFormatConverterStreamT<TFrom, TTo>* getConverter() {
713 return (NumberFormatConverterStreamT<TFrom, TTo>*)p_converter;
717 if (p_stream !=
nullptr) {
718 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
719 getConverter<int8_t, int16_t>()->setStream(*p_stream);
720 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
721 getConverter<int16_t, int8_t>()->setStream(*p_stream);
722 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
723 getConverter<int24_t, int16_t>()->setStream(*p_stream);
724 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
725 getConverter<int16_t, int24_t>()->setStream(*p_stream);
726 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
727 getConverter<int32_t, int16_t>()->setStream(*p_stream);
728 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
729 getConverter<int16_t, int32_t>()->setStream(*p_stream);
734 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
735 getConverter<int8_t, int16_t>()->setOutput(*p_print);
736 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
737 getConverter<int16_t, int8_t>()->setOutput(*p_print);
738 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
739 getConverter<int24_t, int16_t>()->setOutput(*p_print);
740 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
741 getConverter<int16_t, int24_t>()->setOutput(*p_print);
742 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
743 getConverter<int32_t, int16_t>()->setOutput(*p_print);
744 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
745 getConverter<int16_t, int32_t>()->setOutput(*p_print);