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);
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);
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));
361 virtual size_t write(
const uint8_t *data,
size_t len)
override {
363 if (p_print ==
nullptr)
return 0;
366 #ifdef USE_TYPETRAITS
367 if (std::is_same<TFrom, TTo>::value)
return p_print->write(data, len);
369 if (
sizeof(TFrom) ==
sizeof(TTo))
return p_print->write(data, len);
372 size_t samples = len /
sizeof(TFrom);
373 size_t result_size = 0;
374 TFrom *data_source = (TFrom *)data;
377 for (
size_t j = 0; j < samples; j++) {
378 TTo value = NumberConverter::convert<TFrom, TTo>(data_source[j]);
379 result_size += p_print->write((uint8_t *)&value,
sizeof(TTo));
382 int size_bytes =
sizeof(TTo) * samples;
383 buffer.resize(size_bytes);
384 NumberConverter::convertArray<TFrom, TTo>(
385 data_source, (TTo *)buffer.
data(), samples, gain);
386 p_print->write((uint8_t *)buffer.
address(), size_bytes);
393 size_t readBytes(uint8_t *data,
size_t len)
override {
394 LOGD(
"NumberFormatConverterStreamT::readBytes: %d", (
int)len);
395 if (p_stream ==
nullptr)
return 0;
396 size_t samples = len /
sizeof(TTo);
397 TTo *data_target = (TTo *)data;
400 for (
size_t j = 0; j < samples; j++) {
402 p_stream->readBytes((uint8_t *)&source,
sizeof(TFrom));
403 data_target[j] = NumberConverter::convert<TFrom, TTo>(source);
406 buffer.resize(
sizeof(TFrom) * samples);
407 readSamples<TFrom>(p_stream, (TFrom *)buffer.
address(), samples);
408 TFrom *data = (TFrom *)buffer.
address();
409 NumberConverter::convertArray<TFrom, TTo>(data, data_target, samples,
416 virtual int available()
override {
417 return p_stream !=
nullptr ? p_stream->available() : 0;
420 virtual int availableForWrite()
override {
421 return p_print ==
nullptr ? 0 : p_print->availableForWrite();
431 float getByteFactor() {
432 return static_cast<float>(
sizeof(TTo)) /
static_cast<float>(
sizeof(TFrom));
436 SingleBuffer<uint8_t> buffer{0};
437 bool is_buffered =
true;
460 LOGI(
"-> NumberFormatConverterStream:")
472 LOGE(
"sample_rate does not match")
475 if (info.channels != to.channels){
476 LOGE(
"channels do not match")
479 return begin(info, to.bits_per_sample, gain);
482 bool begin(
AudioInfo info,
int toBits,
float gain = 1.0f) {
484 return begin(info.bits_per_sample, toBits, gain);
487 bool begin() {
return begin(from_bit_per_samples, to_bit_per_samples, gain); }
489 void setToBits(uint8_t bits) { to_bit_per_samples = bits; }
491 bool begin(
int from_bit_per_samples,
int to_bit_per_samples,
493 assert(to_bit_per_samples > 0);
496 LOGI(
"begin %d -> %d bits", from_bit_per_samples, to_bit_per_samples);
498 this->from_bit_per_samples = from_bit_per_samples;
499 this->to_bit_per_samples = to_bit_per_samples;
501 if (from_bit_per_samples == to_bit_per_samples) {
502 LOGI(
"no bit conversion: %d -> %d", from_bit_per_samples,
504 }
else if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
505 converter =
new NumberFormatConverterStreamT<int8_t, int16_t>(gain);
506 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
507 converter =
new NumberFormatConverterStreamT<int16_t, int8_t>(gain);
508 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
509 converter =
new NumberFormatConverterStreamT<int24_t, int16_t>(gain);
510 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
511 converter =
new NumberFormatConverterStreamT<int16_t, int24_t>(gain);
512 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
513 converter =
new NumberFormatConverterStreamT<int32_t, int16_t>(gain);
514 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
515 converter =
new NumberFormatConverterStreamT<int16_t, int32_t>(gain);
518 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
522 if (from_bit_per_samples != to_bit_per_samples) {
532 virtual size_t write(
const uint8_t *data,
size_t len)
override {
533 LOGD(
"NumberFormatConverterStream::write: %d", (
int)len);
534 if (p_print ==
nullptr)
return 0;
535 if (from_bit_per_samples == to_bit_per_samples) {
536 return p_print->write(data, len);
539 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
540 return getConverter<int8_t, int16_t>()->write(data, len);
541 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
542 return getConverter<int16_t, int8_t>()->write(data, len);
543 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
544 return getConverter<int24_t, int16_t>()->write(data, len);
545 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
546 return getConverter<int16_t, int24_t>()->write(data, len);
547 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
548 return getConverter<int32_t, int16_t>()->write(data, len);
549 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
550 return getConverter<int16_t, int32_t>()->write(data, len);
552 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
558 size_t readBytes(uint8_t *data,
size_t len)
override {
559 LOGD(
"NumberFormatConverterStream::readBytes: %d", (
int)len);
560 if (from_bit_per_samples == to_bit_per_samples) {
561 return p_stream->readBytes(data, len);
563 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
564 return getConverter<int8_t, int16_t>()->readBytes(data, len);
565 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
566 return getConverter<int16_t, int8_t>()->readBytes(data, len);
567 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
568 return getConverter<int24_t, int16_t>()->readBytes(data, len);
569 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
570 return getConverter<int16_t, int24_t>()->readBytes(data, len);
571 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
572 return getConverter<int32_t, int16_t>()->readBytes(data, len);
573 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
574 return getConverter<int16_t, int32_t>()->readBytes(data, len);
581 virtual int available()
override {
582 if (from_bit_per_samples == to_bit_per_samples) {
583 return p_stream->available();
585 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
586 return getConverter<int8_t, int16_t>()->available();
587 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
588 return getConverter<int16_t, int8_t>()->available();
589 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
590 return getConverter<int24_t, int16_t>()->available();
591 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
592 return getConverter<int16_t, int24_t>()->available();
593 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
594 return getConverter<int32_t, int16_t>()->available();
595 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
596 return getConverter<int16_t, int32_t>()->available();
603 virtual int availableForWrite()
override {
604 if (p_print ==
nullptr)
return 0;
605 if (from_bit_per_samples == to_bit_per_samples) {
606 return p_print->availableForWrite();
608 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
609 return getConverter<int8_t, int16_t>()->availableForWrite();
610 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
611 return getConverter<int16_t, int8_t>()->availableForWrite();
612 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
613 return getConverter<int24_t, int16_t>()->availableForWrite();
614 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
615 return getConverter<int16_t, int24_t>()->availableForWrite();
616 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
617 return getConverter<int32_t, int16_t>()->availableForWrite();
618 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
619 return getConverter<int16_t, int32_t>()->availableForWrite();
626 void setBuffered(
bool flag) {
627 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
628 getConverter<int8_t, int16_t>()->setBuffered(flag);
629 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
630 getConverter<int16_t, int8_t>()->setBuffered(flag);
631 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
632 getConverter<int24_t, int16_t>()->setBuffered(flag);
633 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
634 getConverter<int16_t, int24_t>()->setBuffered(flag);
635 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
636 getConverter<int32_t, int16_t>()->setBuffered(flag);
637 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
638 getConverter<int16_t, int32_t>()->setBuffered(flag);
642 float getByteFactor() {
643 return static_cast<float>(to_bit_per_samples) /
644 static_cast<float>(from_bit_per_samples);
648 void *converter =
nullptr;
649 int from_bit_per_samples = 16;
650 int to_bit_per_samples = 0;
653 template <
typename TFrom,
typename TTo>
654 NumberFormatConverterStreamT<TFrom, TTo> *getConverter() {
655 return (NumberFormatConverterStreamT<TFrom, TTo> *)converter;
659 if (p_stream !=
nullptr) {
660 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
661 getConverter<int8_t, int16_t>()->setStream(*p_stream);
662 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
663 getConverter<int16_t, int8_t>()->setStream(*p_stream);
664 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
665 getConverter<int24_t, int16_t>()->setStream(*p_stream);
666 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
667 getConverter<int16_t, int24_t>()->setStream(*p_stream);
668 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
669 getConverter<int32_t, int16_t>()->setStream(*p_stream);
670 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
671 getConverter<int16_t, int32_t>()->setStream(*p_stream);
676 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
677 getConverter<int8_t, int16_t>()->setOutput(*p_print);
678 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
679 getConverter<int16_t, int8_t>()->setOutput(*p_print);
680 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
681 getConverter<int24_t, int16_t>()->setOutput(*p_print);
682 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
683 getConverter<int16_t, int24_t>()->setOutput(*p_print);
684 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
685 getConverter<int32_t, int16_t>()->setOutput(*p_print);
686 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
687 getConverter<int16_t, int32_t>()->setOutput(*p_print);
721 sampleRateConverter.setStream(io);
727 sampleRateConverter.setStream(io);
732 ReformatBaseStream::setOutput(print);
733 sampleRateConverter.setOutput(print);
738 ReformatBaseStream::setOutput(print);
739 sampleRateConverter.setOutput(print);
746 numberFormatConverter.setAudioInfo(info);
747 channelFormatConverter.setAudioInfo(info);
751 void setAudioInfoOut(
AudioInfo to) { to_cfg = to; }
772 if (getStream() !=
nullptr) {
773 sampleRateConverter.setStream(*getStream());
775 if (getPrint() !=
nullptr) {
776 sampleRateConverter.setOutput(*getPrint());
778 numberFormatConverter.setStream(sampleRateConverter);
779 channelFormatConverter.setStream(numberFormatConverter);
782 bool result = channelFormatConverter.begin(from_cfg, to_cfg.channels);
785 from_actual_cfg.
channels = to_cfg.channels;
787 to_cfg.bits_per_sample);
789 numberFormatConverter.setBuffered(is_buffered);
790 sampleRateConverter.setBuffered(is_buffered);
793 result &= sampleRateConverter.begin(from_actual_cfg, to_cfg.
sample_rate);
799 LOGE(
"begin failed");
804 virtual size_t write(
const uint8_t *data,
size_t len)
override {
805 LOGD(
"FormatConverterStream::write: %d", (
int)len);
807 return channelFormatConverter.write(data, len);
813 float getByteFactor() {
814 return numberFormatConverter.getByteFactor() *
815 channelFormatConverter.getByteFactor();
821 NumberFormatConverterStream numberFormatConverter;
822 ChannelFormatConverterStream channelFormatConverter;
823 ResampleStream sampleRateConverter;
824 bool is_buffered =
true;
829 return (
float)from_cfg.channels / (float)to_cfg.channels *
830 (
float)from_cfg.bits_per_sample / (float)to_cfg.bits_per_sample;