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 LOGI(
"--> ChannelFormatConverterStream");
136 switch (bits_per_sample) {
138 getConverter<int8_t>()->setAudioInfo(cfg);
141 getConverter<int16_t>()->setAudioInfo(cfg);
144 getConverter<int24_t>()->setAudioInfo(cfg);
147 getConverter<int32_t>()->setAudioInfo(cfg);
161 LOGE(
"invalid sample_rate: %d", (
int)to.
sample_rate);
171 bool begin(AudioInfo cfg,
int toChannels) {
172 assert(toChannels != 0);
174 to_channels = toChannels;
175 from_channels = cfg.channels;
176 bits_per_sample = cfg.bits_per_sample;
177 LOGI(
"--> ChannelFormatConverterStream");
179 LOGI(
"begin %d -> %d channels", cfg.channels, toChannels);
180 bool result = setupConverter(cfg.channels, toChannels);
187 bool begin()
override {
return begin(
audioInfo(), to_channels); }
189 void end()
override { cleanupConverter(); }
191 void setToChannels(uint16_t channels) { to_channels = channels; }
193 virtual size_t write(
const uint8_t *data,
size_t len)
override {
194 LOGD(
"ChannelFormatConverterStream::write: %d", (
int)len);
195 if (p_print ==
nullptr)
return 0;
197 switch (bits_per_sample) {
199 return getConverter<int8_t>()->write(data, len);
201 return getConverter<int16_t>()->write(data, len);
203 return getConverter<int24_t>()->write(data, len);
205 return getConverter<int32_t>()->write(data, len);
211 size_t readBytes(uint8_t *data,
size_t len)
override {
212 LOGD(
"ChannelFormatConverterStream::readBytes: %d", (
int)len);
213 switch (bits_per_sample) {
215 return getConverter<int8_t>()->readBytes(data, len);
217 return getConverter<int16_t>()->readBytes(data, len);
219 return getConverter<int24_t>()->readBytes(data, len);
221 return getConverter<int32_t>()->readBytes(data, len);
227 virtual int available()
override {
228 switch (bits_per_sample) {
230 return getConverter<int8_t>()->available();
232 return getConverter<int16_t>()->available();
234 return getConverter<int24_t>()->available();
236 return getConverter<int32_t>()->available();
242 virtual int availableForWrite()
override {
243 switch (bits_per_sample) {
245 return getConverter<int8_t>()->availableForWrite();
247 return getConverter<int16_t>()->availableForWrite();
249 return getConverter<int24_t>()->availableForWrite();
251 return getConverter<int32_t>()->availableForWrite();
257 float getByteFactor()
override {
258 return static_cast<float>(to_channels) /
static_cast<float>(from_channels);
262 void *converter =
nullptr;
263 int bits_per_sample = 0;
267 template <
typename T>
268 ChannelFormatConverterStreamT<T> *getConverter() {
269 return (ChannelFormatConverterStreamT<T> *)converter;
272 void cleanupConverter() {
273 if (converter ==
nullptr)
return;
274 switch (bits_per_sample) {
276 delete getConverter<int8_t>();
280 delete getConverter<int16_t>();
284 delete getConverter<int24_t>();
288 delete getConverter<int32_t>();
294 bool setupConverter(
int fromChannels,
int toChannels) {
297 switch (bits_per_sample) {
299 converter =
new ChannelFormatConverterStreamT<int8_t>(*p_stream);
300 getConverter<int8_t>()->begin(fromChannels, toChannels);
303 converter =
new ChannelFormatConverterStreamT<int16_t>(*p_stream);
304 getConverter<int16_t>()->begin(fromChannels, toChannels);
307 converter =
new ChannelFormatConverterStreamT<int24_t>(*p_stream);
308 getConverter<int24_t>()->begin(fromChannels, toChannels);
311 converter =
new ChannelFormatConverterStreamT<int32_t>(*p_stream);
312 getConverter<int32_t>()->begin(fromChannels, toChannels);
359 bool begin()
override {
360 LOGI(
"begin %d -> %d bits", (
int)
sizeof(TFrom), (
int)
sizeof(TTo));
365 virtual size_t write(
const uint8_t *data,
size_t len)
override {
367 if (p_print ==
nullptr)
return 0;
371 if (std::is_same<TFrom, TTo>::value)
return p_print->write(data, len);
373 if (
sizeof(TFrom) ==
sizeof(TTo))
return p_print->write(data, len);
376 size_t samples = len /
sizeof(TFrom);
377 size_t result_size = 0;
378 TFrom *data_source = (TFrom *)data;
381 for (
size_t j = 0; j < samples; j++) {
382 TTo value = NumberConverter::convert<TFrom, TTo>(data_source[j]);
383 result_size += p_print->write((uint8_t *)&value,
sizeof(TTo));
386 int size_bytes =
sizeof(TTo) * samples;
387 buffer.resize(size_bytes);
388 NumberConverter::convertArray<TFrom, TTo>(
389 data_source, (TTo *)buffer.
data(), samples, gain);
390 p_print->write((uint8_t *)buffer.
address(), size_bytes);
397 size_t readBytes(uint8_t *data,
size_t len)
override {
398 LOGD(
"NumberFormatConverterStreamT::readBytes: %d", (
int)len);
399 if (p_stream ==
nullptr)
return 0;
400 size_t samples = len /
sizeof(TTo);
401 TTo *data_target = (TTo *)data;
404 for (
size_t j = 0; j < samples; j++) {
406 p_stream->readBytes((uint8_t *)&source,
sizeof(TFrom));
407 data_target[j] = NumberConverter::convert<TFrom, TTo>(source);
410 buffer.resize(
sizeof(TFrom) * samples);
411 readSamples<TFrom>(p_stream, (TFrom *)buffer.
address(), samples);
412 TFrom *data = (TFrom *)buffer.
address();
413 NumberConverter::convertArray<TFrom, TTo>(data, data_target, samples,
420 virtual int available()
override {
421 return p_stream !=
nullptr ? p_stream->available() : 0;
424 virtual int availableForWrite()
override {
425 return p_print ==
nullptr ? 0 : p_print->availableForWrite();
435 float getByteFactor()
override {
436 return static_cast<float>(
sizeof(TTo)) /
static_cast<float>(
sizeof(TFrom));
440 SingleBuffer<uint8_t> buffer{0};
441 bool is_buffered =
true;
465 LOGI(
"-> NumberFormatConverterStream:")
477 LOGE(
"sample_rate does not match")
480 if (info.channels != to.channels) {
481 LOGE(
"channels do not match")
484 return begin(info, to.bits_per_sample, gain);
487 bool begin(
AudioInfo info,
int toBits,
float gain = 1.0f) {
489 return begin(info.bits_per_sample, toBits, gain);
492 bool begin()
override {
493 return begin(from_bit_per_samples, to_bit_per_samples, gain);
496 void end()
override { cleanupConverter(); }
498 void setToBits(uint8_t bits) { to_bit_per_samples = bits; }
500 bool begin(
int from_bit_per_samples,
int to_bit_per_samples,
502 LOGI(
"begin %d -> %d bits", from_bit_per_samples, to_bit_per_samples);
504 assert(to_bit_per_samples > 0);
507 if (p_converter !=
nullptr) end();
511 this->from_bit_per_samples = from_bit_per_samples;
512 this->to_bit_per_samples = to_bit_per_samples;
514 if (from_bit_per_samples == to_bit_per_samples) {
515 LOGI(
"no bit conversion: %d -> %d", from_bit_per_samples,
517 }
else if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
519 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
521 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
523 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
525 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
527 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
531 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
535 if (from_bit_per_samples != to_bit_per_samples) {
500 bool begin(
int from_bit_per_samples,
int to_bit_per_samples, {
…}
545 virtual size_t write(
const uint8_t *data,
size_t len)
override {
546 LOGD(
"NumberFormatConverterStream::write: %d", (
int)len);
547 if (p_print ==
nullptr)
return 0;
548 if (from_bit_per_samples == to_bit_per_samples) {
549 return p_print->write(data, len);
552 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
553 return getConverter<int8_t, int16_t>()->write(data, len);
554 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
555 return getConverter<int16_t, int8_t>()->write(data, len);
556 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
557 return getConverter<int24_t, int16_t>()->write(data, len);
558 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
559 return getConverter<int16_t, int24_t>()->write(data, len);
560 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
561 return getConverter<int32_t, int16_t>()->write(data, len);
562 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
563 return getConverter<int16_t, int32_t>()->write(data, len);
565 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
571 size_t readBytes(uint8_t *data,
size_t len)
override {
572 LOGD(
"NumberFormatConverterStream::readBytes: %d", (
int)len);
573 if (from_bit_per_samples == to_bit_per_samples) {
574 return p_stream->readBytes(data, len);
576 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
577 return getConverter<int8_t, int16_t>()->readBytes(data, len);
578 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
579 return getConverter<int16_t, int8_t>()->readBytes(data, len);
580 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
581 return getConverter<int24_t, int16_t>()->readBytes(data, len);
582 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
583 return getConverter<int16_t, int24_t>()->readBytes(data, len);
584 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
585 return getConverter<int32_t, int16_t>()->readBytes(data, len);
586 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
587 return getConverter<int16_t, int32_t>()->readBytes(data, len);
594 virtual int available()
override {
595 if (from_bit_per_samples == to_bit_per_samples) {
596 return p_stream->available();
598 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
599 return getConverter<int8_t, int16_t>()->available();
600 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
601 return getConverter<int16_t, int8_t>()->available();
602 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
603 return getConverter<int24_t, int16_t>()->available();
604 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
605 return getConverter<int16_t, int24_t>()->available();
606 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
607 return getConverter<int32_t, int16_t>()->available();
608 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
609 return getConverter<int16_t, int32_t>()->available();
616 virtual int availableForWrite()
override {
617 if (p_print ==
nullptr)
return 0;
618 if (from_bit_per_samples == to_bit_per_samples) {
619 return p_print->availableForWrite();
621 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
622 return getConverter<int8_t, int16_t>()->availableForWrite();
623 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
624 return getConverter<int16_t, int8_t>()->availableForWrite();
625 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
626 return getConverter<int24_t, int16_t>()->availableForWrite();
627 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
628 return getConverter<int16_t, int24_t>()->availableForWrite();
629 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
630 return getConverter<int32_t, int16_t>()->availableForWrite();
631 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
632 return getConverter<int16_t, int32_t>()->availableForWrite();
639 void setBuffered(
bool flag) {
640 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
641 getConverter<int8_t, int16_t>()->setBuffered(flag);
642 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
643 getConverter<int16_t, int8_t>()->setBuffered(flag);
644 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
645 getConverter<int24_t, int16_t>()->setBuffered(flag);
646 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
647 getConverter<int16_t, int24_t>()->setBuffered(flag);
648 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
649 getConverter<int32_t, int16_t>()->setBuffered(flag);
650 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
651 getConverter<int16_t, int32_t>()->setBuffered(flag);
655 float getByteFactor()
override {
656 return static_cast<float>(to_bit_per_samples) /
657 static_cast<float>(from_bit_per_samples);
661 void *p_converter =
nullptr;
662 int from_bit_per_samples = 16;
663 int to_bit_per_samples = 0;
666 void cleanupConverter() {
667 if (p_converter ==
nullptr)
return;
669 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
670 delete static_cast<NumberFormatConverterStreamT<int8_t, int16_t> *
>(
672 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
673 delete static_cast<NumberFormatConverterStreamT<int16_t, int8_t> *
>(
675 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
676 delete static_cast<NumberFormatConverterStreamT<int24_t, int16_t> *
>(
678 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
679 delete static_cast<NumberFormatConverterStreamT<int16_t, int24_t> *
>(
681 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
682 delete static_cast<NumberFormatConverterStreamT<int32_t, int16_t> *
>(
684 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
685 delete static_cast<NumberFormatConverterStreamT<int16_t, int32_t> *
>(
690 p_converter =
nullptr;
693 template <
typename TFrom,
typename TTo>
694 NumberFormatConverterStreamT<TFrom, TTo> *getConverter() {
695 return (NumberFormatConverterStreamT<TFrom, TTo> *)p_converter;
699 if (p_stream !=
nullptr) {
700 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
701 getConverter<int8_t, int16_t>()->setStream(*p_stream);
702 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
703 getConverter<int16_t, int8_t>()->setStream(*p_stream);
704 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
705 getConverter<int24_t, int16_t>()->setStream(*p_stream);
706 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
707 getConverter<int16_t, int24_t>()->setStream(*p_stream);
708 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
709 getConverter<int32_t, int16_t>()->setStream(*p_stream);
710 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
711 getConverter<int16_t, int32_t>()->setStream(*p_stream);
716 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
717 getConverter<int8_t, int16_t>()->setOutput(*p_print);
718 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
719 getConverter<int16_t, int8_t>()->setOutput(*p_print);
720 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
721 getConverter<int24_t, int16_t>()->setOutput(*p_print);
722 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
723 getConverter<int16_t, int24_t>()->setOutput(*p_print);
724 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
725 getConverter<int32_t, int16_t>()->setOutput(*p_print);
726 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
727 getConverter<int16_t, int32_t>()->setOutput(*p_print);