2 #include "AudioTools/AudioStreams.h"
3 #include "AudioTools/ResampleStream.h"
22 bool begin(
int fromChannels,
int toChannels) {
23 LOGI(
"begin %d -> %d channels", fromChannels, toChannels);
24 from_channels = fromChannels;
25 to_channels = toChannels;
26 factor =
static_cast<float>(toChannels) /
static_cast<float>(fromChannels);
28 converter.setSourceChannels(from_channels);
29 converter.setTargetChannels(to_channels);
34 virtual size_t write(
const uint8_t *data,
size_t size)
override {
36 if (from_channels == to_channels) {
37 return p_print->write(data, size);
39 size_t resultBytes = convert(data, size);
40 assert(resultBytes = factor * size);
41 p_print->write((uint8_t *)buffer.data(), resultBytes);
45 size_t readBytes(uint8_t *data,
size_t size)
override {
47 if (p_stream ==
nullptr)
return 0;
48 if (from_channels == to_channels) {
49 return p_stream->readBytes(data, size);
51 size_t in_bytes = 1.0f / factor * size;
52 bufferTmp.resize(in_bytes);
53 p_stream->readBytes(bufferTmp.data(), in_bytes);
54 size_t resultBytes = convert(bufferTmp.data(), in_bytes);
55 assert(size == resultBytes);
56 memcpy(data, (uint8_t *)buffer.data(), size);
60 void setAudioInfo(
AudioInfo cfg)
override {
62 AudioStream::setAudioInfo(cfg);
65 virtual int available()
override {
66 return p_stream !=
nullptr ? p_stream->available() : 0;
69 virtual int availableForWrite()
override {
70 return 1.0f / factor * p_print->availableForWrite();
73 float getByteFactor() {
return static_cast<float>(to_channels)/
static_cast<float>(from_channels);}
76 int from_channels = 2;
84 size_t convert(
const uint8_t *in_data,
size_t size) {
86 size_t result_samples = size /
sizeof(T) * factor;
87 buffer.resize(result_samples);
89 converter.convert((uint8_t *)buffer.data(), (uint8_t *)in_data, size);
90 if (result != result_samples *
sizeof(T)) {
91 LOGE(
"size %d -> result: %d - expeced: %d", (
int)size, (
int)result,
92 static_cast<int>(result_samples *
sizeof(T)));
113 void setAudioInfo(
AudioInfo cfg)
override {
116 AudioStream::setAudioInfo(cfg);
117 switch (bits_per_sample) {
119 getConverter<int8_t>()->setAudioInfo(cfg);
122 getConverter<int16_t>()->setAudioInfo(cfg);
125 getConverter<int24_t>()->setAudioInfo(cfg);
128 getConverter<int32_t>()->setAudioInfo(cfg);
133 bool begin(
AudioInfo cfg,
int toChannels) {
134 assert(toChannels!=0);
135 to_channels = toChannels;
138 AudioStream::setAudioInfo(cfg);
139 LOGI(
"begin %d -> %d channels", cfg.
channels, toChannels);
140 bool result = setupConverter(cfg.
channels, toChannels);
147 virtual size_t write(
const uint8_t *data,
size_t size)
override {
148 LOGD(
"ChannelFormatConverterStream::write: %d", (
int)size);
149 switch (bits_per_sample) {
151 return getConverter<int8_t>()->write(data, size);
153 return getConverter<int16_t>()->write(data, size);
155 return getConverter<int24_t>()->write(data, size);
157 return getConverter<int32_t>()->write(data, size);
163 size_t readBytes(uint8_t *data,
size_t size)
override {
164 LOGD(
"ChannelFormatConverterStream::readBytes: %d", (
int)size);
165 switch (bits_per_sample) {
167 return getConverter<int8_t>()->readBytes(data, size);
169 return getConverter<int16_t>()->readBytes(data, size);
171 return getConverter<int24_t>()->readBytes(data, size);
173 return getConverter<int32_t>()->readBytes(data, size);
179 virtual int available()
override {
180 switch (bits_per_sample) {
182 return getConverter<int8_t>()->available();
184 return getConverter<int16_t>()->available();
186 return getConverter<int24_t>()->available();
188 return getConverter<int32_t>()->available();
194 virtual int availableForWrite()
override {
195 switch (bits_per_sample) {
197 return getConverter<int8_t>()->availableForWrite();
199 return getConverter<int16_t>()->availableForWrite();
201 return getConverter<int24_t>()->availableForWrite();
203 return getConverter<int32_t>()->availableForWrite();
209 float getByteFactor() {
return static_cast<float>(to_channels)/
static_cast<float>(from_channels);}
213 int bits_per_sample = 0;
217 template <
typename T>
222 bool setupConverter(
int fromChannels,
int toChannels) {
224 if (p_stream !=
nullptr) {
225 switch (bits_per_sample) {
228 getConverter<int8_t>()->begin(fromChannels, toChannels);
232 getConverter<int16_t>()->begin(fromChannels, toChannels);
236 getConverter<int24_t>()->begin(fromChannels, toChannels);
240 getConverter<int32_t>()->begin(fromChannels, toChannels);
246 switch (bits_per_sample) {
249 getConverter<int8_t>()->begin(fromChannels, toChannels);
253 getConverter<int16_t>()->begin(fromChannels, toChannels);
257 getConverter<int24_t>()->begin(fromChannels, toChannels);
261 getConverter<int32_t>()->begin(fromChannels, toChannels);
283 template <
typename TFrom,
typename TTo>
293 void setAudioInfo (
AudioInfo info)
override {
305 if (to_format) notifyAudioChange(to_format);
308 bool begin()
override {
309 LOGI(
"begin %d -> %d bits", (
int)
sizeof(TFrom),(
int)
sizeof(TTo));
313 virtual size_t write(
const uint8_t *data,
size_t size)
override {
315 if (
sizeof(TFrom) ==
sizeof(TTo))
return p_print->write(data, size);
316 size_t samples = size /
sizeof(TFrom);
317 size_t result_size = 0;
318 TFrom *data_source = (TFrom *)data;
321 for (
size_t j = 0; j < samples; j++) {
322 TTo value = NumberConverter::convert<TFrom, TTo>(data_source[j]);
323 result_size += p_print->write((uint8_t *)&value,
sizeof(TTo));
326 int size_bytes =
sizeof(TTo) * samples;
327 buffer.resize(size_bytes);
328 NumberConverter::convertArray<TFrom, TTo>(data_source,(TTo*) buffer.
data(), samples, gain);
329 p_print->write((uint8_t *)buffer.
address(), size_bytes);
336 size_t readBytes(uint8_t *data,
size_t size)
override {
337 LOGD(
"NumberFormatConverterStreamT::readBytes: %d", (
int)size);
338 if (p_stream ==
nullptr)
return 0;
339 size_t samples = size /
sizeof(TTo);
340 TTo *data_target = (TTo *)data;
343 for (
size_t j = 0; j < samples; j++) {
345 p_stream->readBytes((uint8_t *)&source,
sizeof(TFrom));
346 data_target[j] = NumberConverter::convert<TFrom, TTo>(source);
349 buffer.resize(
sizeof(TFrom) * samples);
350 readSamples<TFrom>(p_stream, (TFrom *)buffer.
address(), samples);
351 TFrom *data = (TFrom *)buffer.
address();
352 NumberConverter::convertArray<TFrom, TTo>(data, data_target, samples, gain);
358 virtual int available()
override {
359 return p_stream !=
nullptr ? p_stream->available() : 0;
362 virtual int availableForWrite()
override {
363 return p_print->availableForWrite();
375 float getByteFactor() {
return static_cast<float>(
sizeof(TTo))/
static_cast<float>(
sizeof(TFrom));}
378 SingleBuffer<uint8_t> buffer{0};
379 bool is_buffered =
true;
399 void setAudioInfo (
AudioInfo info)
override {
408 if (to_format) notifyAudioChange(to_format);
411 bool begin(
AudioInfo info,
int to_bit_per_samples,
float gain=1.0f) {
416 bool begin(
int from_bit_per_samples,
int to_bit_per_samples,
float gain = 1.0) {
417 assert(to_bit_per_samples > 0);
418 LOGI(
"begin %d -> %d bits", from_bit_per_samples, to_bit_per_samples);
420 this->from_bit_per_samples = from_bit_per_samples;
421 this->to_bit_per_samples = to_bit_per_samples;
423 if (from_bit_per_samples == to_bit_per_samples) {
424 LOGI(
"no bit conversion: %d -> %d", from_bit_per_samples,
426 }
else if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
428 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
430 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
432 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
434 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
436 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
440 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
444 if (from_bit_per_samples != to_bit_per_samples){
454 virtual size_t write(
const uint8_t *data,
size_t size)
override {
455 LOGD(
"NumberFormatConverterStream::write: %d", (
int) size);
456 if (from_bit_per_samples == to_bit_per_samples) {
457 return p_print->write(data, size);
460 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
461 return getConverter<int8_t, int16_t>()->write(data, size);
462 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
463 return getConverter<int16_t, int8_t>()->write(data, size);
464 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
465 return getConverter<int24_t, int16_t>()->write(data, size);
466 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
467 return getConverter<int16_t, int24_t>()->write(data, size);
468 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
469 return getConverter<int32_t, int16_t>()->write(data, size);
470 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
471 return getConverter<int16_t, int32_t>()->write(data, size);
473 LOGE(
"bit combination not supported %d -> %d", from_bit_per_samples,
479 size_t readBytes(uint8_t *data,
size_t size)
override {
480 LOGD(
"NumberFormatConverterStream::readBytes: %d", (
int)size);
481 if (from_bit_per_samples == to_bit_per_samples) {
482 return p_stream->readBytes(data, size);
484 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
485 return getConverter<int8_t, int16_t>()->readBytes(data, size);
486 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
487 return getConverter<int16_t, int8_t>()->readBytes(data, size);
488 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
489 return getConverter<int24_t, int16_t>()->readBytes(data, size);
490 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
491 return getConverter<int16_t, int24_t>()->readBytes(data, size);
492 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
493 return getConverter<int32_t, int16_t>()->readBytes(data, size);
494 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
495 return getConverter<int16_t, int32_t>()->readBytes(data, size);
502 virtual int available()
override {
503 if (from_bit_per_samples == to_bit_per_samples) {
504 return p_stream->available();
506 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
507 return getConverter<int8_t, int16_t>()->available();
508 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
509 return getConverter<int16_t, int8_t>()->available();
510 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
511 return getConverter<int24_t, int16_t>()->available();
512 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
513 return getConverter<int16_t, int24_t>()->available();
514 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
515 return getConverter<int32_t, int16_t>()->available();
516 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
517 return getConverter<int16_t, int32_t>()->available();
524 virtual int availableForWrite()
override {
525 if (from_bit_per_samples == to_bit_per_samples) {
526 return p_print->availableForWrite();
528 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
529 return getConverter<int8_t, int16_t>()->availableForWrite();
530 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
531 return getConverter<int16_t, int8_t>()->availableForWrite();
532 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
533 return getConverter<int24_t, int16_t>()->availableForWrite();
534 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
535 return getConverter<int16_t, int24_t>()->availableForWrite();
536 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
537 return getConverter<int32_t, int16_t>()->availableForWrite();
538 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
539 return getConverter<int16_t, int32_t>()->availableForWrite();
546 void setBuffered(
bool flag) {
547 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
548 getConverter<int8_t, int16_t>()->setBuffered(flag);
549 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
550 getConverter<int16_t, int8_t>()->setBuffered(flag);
551 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
552 getConverter<int24_t, int16_t>()->setBuffered(flag);
553 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
554 getConverter<int16_t, int24_t>()->setBuffered(flag);
555 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
556 getConverter<int32_t, int16_t>()->setBuffered(flag);
557 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
558 getConverter<int16_t, int32_t>()->setBuffered(flag);
562 float getByteFactor() {
return static_cast<float>(to_bit_per_samples)/
static_cast<float>(from_bit_per_samples);}
565 void *converter =
nullptr;
566 int from_bit_per_samples = 0;
567 int to_bit_per_samples = 0;
569 template <
typename TFrom,
typename TTo>
575 if (p_stream !=
nullptr) {
576 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
577 getConverter<int8_t, int16_t>()->setStream(*p_stream);
578 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
579 getConverter<int16_t, int8_t>()->setStream(*p_stream);
580 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
581 getConverter<int24_t, int16_t>()->setStream(*p_stream);
582 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
583 getConverter<int16_t, int24_t>()->setStream(*p_stream);
584 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
585 getConverter<int32_t, int16_t>()->setStream(*p_stream);
586 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
587 getConverter<int16_t, int32_t>()->setStream(*p_stream);
592 if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
593 getConverter<int8_t, int16_t>()->setStream(*p_print);
594 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
595 getConverter<int16_t, int8_t>()->setStream(*p_print);
596 }
else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
597 getConverter<int24_t, int16_t>()->setStream(*p_print);
598 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
599 getConverter<int16_t, int24_t>()->setStream(*p_print);
600 }
else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
601 getConverter<int32_t, int16_t>()->setStream(*p_print);
602 }
else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
603 getConverter<int16_t, int32_t>()->setStream(*p_print);
625 to_cfg = stream.audioInfo();
629 to_cfg = print.audioInfo();
633 void setStream(
Stream &io)
override {
636 ReformatBaseStream::setStream(io);
637 sampleRateConverter.setStream(io);
643 ReformatBaseStream::setStream(io);
644 sampleRateConverter.setStream(io);
647 void setStream(
Print &print)
override {
650 ReformatBaseStream::setStream(print);
651 sampleRateConverter.setStream(print);
657 ReformatBaseStream::setStream(print);
658 sampleRateConverter.setStream(print);
661 void setAudioInfo(
AudioInfo info)
override {
664 sampleRateConverter.setAudioInfo(info);
665 ReformatBaseStream::setAudioInfo(info);
679 if (getStream()!=
nullptr){
680 sampleRateConverter.setStream(*getStream());
682 if(getPrint()!=
nullptr){
683 sampleRateConverter.setStream(*getPrint());
685 numberFormatConverter.setStream(sampleRateConverter);
686 channelFormatConverter.setStream(numberFormatConverter);
689 bool result = channelFormatConverter.begin(from_cfg, to_cfg.
channels);
696 numberFormatConverter.setBuffered(is_buffered);
701 result &= sampleRateConverter.begin(from_actual_cfg, to_cfg.
sample_rate);
704 if (getStream()!=
nullptr){
709 LOGE(
"begin failed");
714 virtual size_t write(
const uint8_t *data,
size_t size)
override {
715 LOGD(
"FormatConverterStream::write: %d", (
int)size);
716 return channelFormatConverter.write(data, size);
721 is_buffered = active;
724 float getByteFactor() {
return numberFormatConverter.getByteFactor()*channelFormatConverter.getByteFactor();}
729 NumberFormatConverterStream numberFormatConverter;
730 ChannelFormatConverterStream channelFormatConverter;
731 ResampleStream sampleRateConverter;
732 bool is_buffered =
true;
737 return (
float)from_cfg.channels / (float)to_cfg.channels *
738 (
float)from_cfg.bits_per_sample / (float)to_cfg.bits_per_sample;