3 #include "AudioTools/CoreAudio/AudioStreams.h"
4 #include "AudioTools/CoreAudio/ResampleStream.h"
23 bool begin(
int fromChannels,
int toChannels) {
24 LOGI(
"begin %d -> %d channels", fromChannels, toChannels);
25 is_output_notify =
false;
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() {
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() {
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)));
133 LOGI(
"--> ChannelFormatConverterStream");
135 switch (bits_per_sample) {
137 getConverter<int8_t>()->setAudioInfo(cfg);
140 getConverter<int16_t>()->setAudioInfo(cfg);
143 getConverter<int24_t>()->setAudioInfo(cfg);
146 getConverter<int32_t>()->setAudioInfo(cfg);
160 LOGE(
"invalid sample_rate: %d", (
int)to.
sample_rate);
170 bool begin(AudioInfo cfg,
int toChannels) {
171 assert(toChannels != 0);
172 is_output_notify =
false;
173 to_channels = toChannels;
174 from_channels = cfg.channels;
175 bits_per_sample = cfg.bits_per_sample;
176 LOGI(
"--> ChannelFormatConverterStream");
178 LOGI(
"begin %d -> %d channels", cfg.channels, toChannels);
179 bool result = setupConverter(cfg.channels, toChannels);
186 bool begin() {
return begin(
audioInfo(), to_channels); }
188 void setToChannels(uint16_t channels) { to_channels = channels; }
190 virtual size_t write(
const uint8_t *data,
size_t len)
override {
191 LOGD(
"ChannelFormatConverterStream::write: %d", (
int)len);
192 if (p_print ==
nullptr)
return 0;
194 switch (bits_per_sample) {
196 return getConverter<int8_t>()->write(data, len);
198 return getConverter<int16_t>()->write(data, len);
200 return getConverter<int24_t>()->write(data, len);
202 return getConverter<int32_t>()->write(data, len);
208 size_t readBytes(uint8_t *data,
size_t len)
override {
209 LOGD(
"ChannelFormatConverterStream::readBytes: %d", (
int)len);
210 switch (bits_per_sample) {
212 return getConverter<int8_t>()->readBytes(data, len);
214 return getConverter<int16_t>()->readBytes(data, len);
216 return getConverter<int24_t>()->readBytes(data, len);
218 return getConverter<int32_t>()->readBytes(data, len);
224 virtual int available()
override {
225 switch (bits_per_sample) {
227 return getConverter<int8_t>()->available();
229 return getConverter<int16_t>()->available();
231 return getConverter<int24_t>()->available();
233 return getConverter<int32_t>()->available();
239 virtual int availableForWrite()
override {
240 switch (bits_per_sample) {
242 return getConverter<int8_t>()->availableForWrite();
244 return getConverter<int16_t>()->availableForWrite();
246 return getConverter<int24_t>()->availableForWrite();
248 return getConverter<int32_t>()->availableForWrite();
254 float getByteFactor() {
255 return static_cast<float>(to_channels) /
static_cast<float>(from_channels);
260 int bits_per_sample = 0;
264 template <
typename T>
265 ChannelFormatConverterStreamT<T> *getConverter() {
266 return (ChannelFormatConverterStreamT<T> *)converter;
269 bool setupConverter(
int fromChannels,
int toChannels) {
271 if (p_stream !=
nullptr) {
272 switch (bits_per_sample) {
274 converter =
new ChannelFormatConverterStreamT<int8_t>(*p_stream);
275 getConverter<int8_t>()->begin(fromChannels, toChannels);
278 converter =
new ChannelFormatConverterStreamT<int16_t>(*p_stream);
279 getConverter<int16_t>()->begin(fromChannels, toChannels);
282 converter =
new ChannelFormatConverterStreamT<int24_t>(*p_stream);
283 getConverter<int24_t>()->begin(fromChannels, toChannels);
286 converter =
new ChannelFormatConverterStreamT<int32_t>(*p_stream);
287 getConverter<int32_t>()->begin(fromChannels, toChannels);
293 switch (bits_per_sample) {
295 converter =
new ChannelFormatConverterStreamT<int8_t>(*p_print);
296 getConverter<int8_t>()->begin(fromChannels, toChannels);
299 converter =
new ChannelFormatConverterStreamT<int16_t>(*p_print);
300 getConverter<int16_t>()->begin(fromChannels, toChannels);
303 converter =
new ChannelFormatConverterStreamT<int24_t>(*p_print);
304 getConverter<int24_t>()->begin(fromChannels, toChannels);
307 converter =
new ChannelFormatConverterStreamT<int32_t>(*p_print);
308 getConverter<int32_t>()->begin(fromChannels, toChannels);
330 template <
typename TFrom,
typename TTo>
355 bool begin()
override {
356 LOGI(
"begin %d -> %d bits", (
int)
sizeof(TFrom), (
int)
sizeof(TTo));
357 is_output_notify =
false;
361 virtual size_t write(
const uint8_t *data,
size_t len)
override {
363 if (p_print ==
nullptr)
return 0;
365 if (
sizeof(TFrom) ==
sizeof(TTo))
return p_print->write(data, len);
366 size_t samples = len /
sizeof(TFrom);
367 size_t result_size = 0;
368 TFrom *data_source = (TFrom *)data;
371 for (
size_t j = 0; j < samples; j++) {
372 TTo value = NumberConverter::convert<TFrom, TTo>(data_source[j]);
373 result_size += p_print->write((uint8_t *)&value,
sizeof(TTo));
376 int size_bytes =
sizeof(TTo) * samples;
377 buffer.resize(size_bytes);
378 NumberConverter::convertArray<TFrom, TTo>(
379 data_source, (TTo *)buffer.
data(), samples, gain);
380 p_print->write((uint8_t *)buffer.
address(), size_bytes);
387 size_t readBytes(uint8_t *data,
size_t len)
override {
388 LOGD(
"NumberFormatConverterStreamT::readBytes: %d", (
int)len);
389 if (p_stream ==
nullptr)
return 0;
390 size_t samples = len /
sizeof(TTo);
391 TTo *data_target = (TTo *)data;
394 for (
size_t j = 0; j < samples; j++) {
396 p_stream->readBytes((uint8_t *)&source,
sizeof(TFrom));
397 data_target[j] = NumberConverter::convert<TFrom, TTo>(source);
400 buffer.resize(
sizeof(TFrom) * samples);
401 readSamples<TFrom>(p_stream, (TFrom *)buffer.
address(), samples);
402 TFrom *data = (TFrom *)buffer.
address();
403 NumberConverter::convertArray<TFrom, TTo>(data, data_target, samples,
410 virtual int available()
override {
411 return p_stream !=
nullptr ? p_stream->available() : 0;
414 virtual int availableForWrite()
override {
415 return p_print ==
nullptr ? 0 : p_print->availableForWrite();
425 float getByteFactor() {
426 return static_cast<float>(
sizeof(TTo)) /
static_cast<float>(
sizeof(TFrom));
430 SingleBuffer<uint8_t> buffer{0};
431 bool is_buffered =
true;
454 LOGI(
"-> NumberFormatConverterStream:")
466 LOGE(
"sample_rate does not match")
469 if (info.channels != to.channels){
470 LOGE(
"channels do not match")
473 return begin(info, to.bits_per_sample, gain);
476 bool begin(
AudioInfo info,
int toBits,
float gain = 1.0f) {
478 return begin(info.bits_per_sample, toBits, gain);
481 bool begin() {
return begin(from_bit_per_samples, to_bit_per_samples, gain); }
483 void setToBits(uint8_t bits) { to_bit_per_samples = bits; }
485 bool begin(
int from_bit_per_samples,
int to_bit_per_samples,
487 assert(to_bit_per_samples > 0);
488 is_output_notify =
false;
490 LOGI(
"begin %d -> %d bits", from_bit_per_samples, to_bit_per_samples);
492 this->from_bit_per_samples = from_bit_per_samples;
493 this->to_bit_per_samples = to_bit_per_samples;
495 if (from_bit_per_samples == to_bit_per_samples) {
496 LOGI(
"no bit conversion: %d -> %d", from_bit_per_samples,
498 }
else if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
499 converter =
new NumberFormatConverterStreamT<int8_t, int16_t>(gain);
500 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
501 converter =
new NumberFormatConverterStreamT<int16_t, int8_t>(gain);
502 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
503 converter =
new NumberFormatConverterStreamT<int24_t, int16_t>(gain);
504 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
505 converter =
new NumberFormatConverterStreamT<int16_t, int24_t>(gain);
506 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
507 converter =
new NumberFormatConverterStreamT<int32_t, int16_t>(gain);
508 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
509 converter =
new NumberFormatConverterStreamT<int16_t, int32_t>(gain);
512 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
516 if (from_bit_per_samples != to_bit_per_samples) {
526 virtual size_t write(
const uint8_t *data,
size_t len)
override {
527 LOGD(
"NumberFormatConverterStream::write: %d", (
int)len);
528 if (p_print ==
nullptr)
return 0;
529 if (from_bit_per_samples == to_bit_per_samples) {
530 return p_print->write(data, len);
533 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
534 return getConverter<int8_t, int16_t>()->write(data, len);
535 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
536 return getConverter<int16_t, int8_t>()->write(data, len);
537 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
538 return getConverter<int24_t, int16_t>()->write(data, len);
539 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
540 return getConverter<int16_t, int24_t>()->write(data, len);
541 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
542 return getConverter<int32_t, int16_t>()->write(data, len);
543 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
544 return getConverter<int16_t, int32_t>()->write(data, len);
546 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
552 size_t readBytes(uint8_t *data,
size_t len)
override {
553 LOGD(
"NumberFormatConverterStream::readBytes: %d", (
int)len);
554 if (from_bit_per_samples == to_bit_per_samples) {
555 return p_stream->readBytes(data, len);
557 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
558 return getConverter<int8_t, int16_t>()->readBytes(data, len);
559 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
560 return getConverter<int16_t, int8_t>()->readBytes(data, len);
561 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
562 return getConverter<int24_t, int16_t>()->readBytes(data, len);
563 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
564 return getConverter<int16_t, int24_t>()->readBytes(data, len);
565 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
566 return getConverter<int32_t, int16_t>()->readBytes(data, len);
567 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
568 return getConverter<int16_t, int32_t>()->readBytes(data, len);
575 virtual int available()
override {
576 if (from_bit_per_samples == to_bit_per_samples) {
577 return p_stream->available();
579 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
580 return getConverter<int8_t, int16_t>()->available();
581 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
582 return getConverter<int16_t, int8_t>()->available();
583 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
584 return getConverter<int24_t, int16_t>()->available();
585 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
586 return getConverter<int16_t, int24_t>()->available();
587 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
588 return getConverter<int32_t, int16_t>()->available();
589 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
590 return getConverter<int16_t, int32_t>()->available();
597 virtual int availableForWrite()
override {
598 if (p_print ==
nullptr)
return 0;
599 if (from_bit_per_samples == to_bit_per_samples) {
600 return p_print->availableForWrite();
602 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
603 return getConverter<int8_t, int16_t>()->availableForWrite();
604 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
605 return getConverter<int16_t, int8_t>()->availableForWrite();
606 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
607 return getConverter<int24_t, int16_t>()->availableForWrite();
608 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
609 return getConverter<int16_t, int24_t>()->availableForWrite();
610 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
611 return getConverter<int32_t, int16_t>()->availableForWrite();
612 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
613 return getConverter<int16_t, int32_t>()->availableForWrite();
620 void setBuffered(
bool flag) {
621 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
622 getConverter<int8_t, int16_t>()->setBuffered(flag);
623 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
624 getConverter<int16_t, int8_t>()->setBuffered(flag);
625 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
626 getConverter<int24_t, int16_t>()->setBuffered(flag);
627 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
628 getConverter<int16_t, int24_t>()->setBuffered(flag);
629 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
630 getConverter<int32_t, int16_t>()->setBuffered(flag);
631 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
632 getConverter<int16_t, int32_t>()->setBuffered(flag);
636 float getByteFactor() {
637 return static_cast<float>(to_bit_per_samples) /
638 static_cast<float>(from_bit_per_samples);
642 void *converter =
nullptr;
643 int from_bit_per_samples = 16;
644 int to_bit_per_samples = 0;
647 template <
typename TFrom,
typename TTo>
648 NumberFormatConverterStreamT<TFrom, TTo> *getConverter() {
649 return (NumberFormatConverterStreamT<TFrom, TTo> *)converter;
653 if (p_stream !=
nullptr) {
654 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
655 getConverter<int8_t, int16_t>()->setStream(*p_stream);
656 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
657 getConverter<int16_t, int8_t>()->setStream(*p_stream);
658 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
659 getConverter<int24_t, int16_t>()->setStream(*p_stream);
660 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
661 getConverter<int16_t, int24_t>()->setStream(*p_stream);
662 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
663 getConverter<int32_t, int16_t>()->setStream(*p_stream);
664 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
665 getConverter<int16_t, int32_t>()->setStream(*p_stream);
670 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
671 getConverter<int8_t, int16_t>()->setOutput(*p_print);
672 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
673 getConverter<int16_t, int8_t>()->setOutput(*p_print);
674 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
675 getConverter<int24_t, int16_t>()->setOutput(*p_print);
676 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
677 getConverter<int16_t, int24_t>()->setOutput(*p_print);
678 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
679 getConverter<int32_t, int16_t>()->setOutput(*p_print);
680 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
681 getConverter<int16_t, int32_t>()->setOutput(*p_print);
715 sampleRateConverter.setStream(io);
721 sampleRateConverter.setStream(io);
726 ReformatBaseStream::setOutput(print);
727 sampleRateConverter.setOutput(print);
732 ReformatBaseStream::setOutput(print);
733 sampleRateConverter.setOutput(print);
740 numberFormatConverter.setAudioInfo(info);
741 channelFormatConverter.setAudioInfo(info);
745 void setAudioInfoOut(
AudioInfo to) { to_cfg = to; }
764 is_output_notify =
false;
766 if (getStream() !=
nullptr) {
767 sampleRateConverter.setStream(*getStream());
769 if (getPrint() !=
nullptr) {
770 sampleRateConverter.setOutput(*getPrint());
772 numberFormatConverter.setStream(sampleRateConverter);
773 channelFormatConverter.setStream(numberFormatConverter);
776 bool result = channelFormatConverter.begin(from_cfg, to_cfg.channels);
779 from_actual_cfg.
channels = to_cfg.channels;
781 to_cfg.bits_per_sample);
783 numberFormatConverter.setBuffered(is_buffered);
784 sampleRateConverter.setBuffered(is_buffered);
787 result &= sampleRateConverter.begin(from_actual_cfg, to_cfg.
sample_rate);
793 LOGE(
"begin failed");
798 virtual size_t write(
const uint8_t *data,
size_t len)
override {
799 LOGD(
"FormatConverterStream::write: %d", (
int)len);
801 return channelFormatConverter.write(data, len);
807 float getByteFactor() {
808 return numberFormatConverter.getByteFactor() *
809 channelFormatConverter.getByteFactor();
815 NumberFormatConverterStream numberFormatConverter;
816 ChannelFormatConverterStream channelFormatConverter;
817 ResampleStream sampleRateConverter;
818 bool is_buffered =
true;
823 return (
float)from_cfg.channels / (float)to_cfg.channels *
824 (
float)from_cfg.bits_per_sample / (float)to_cfg.bits_per_sample;