2#include "AudioTools/CoreAudio/AudioOutput.h"
3#include "AudioTools/CoreAudio/AudioStreams.h"
5#ifndef MAX_ZERO_READ_COUNT
6#define MAX_ZERO_READ_COUNT 3
9#ifndef CHANNEL_SELECT_BUFFER_SIZE
10#define CHANNEL_SELECT_BUFFER_SIZE 256
32 p_transform = transform;
33 if (transform ==
nullptr) {
34 LOGE(
"transform is NULL");
37 if (p_stream ==
nullptr) {
38 LOGE(
"p_stream is NULL");
47 result_queue_buffer.
resize(size);
51 size_t readBytes(uint8_t* data,
size_t len) {
52 LOGD(
"TransformationReader::readBytes: %d", (
int)len);
57 if (p_stream ==
nullptr) {
58 LOGE(
"p_stream is NULL");
63 if (buffer.size() == 0) {
64 int size = (0.5f / p_transform->getByteFactor() * len);
67 LOGI(
"read size: %d", size);
71 if (result_queue_buffer.
size() == 0) {
73 int rb_size = len * result_queue_factor;
74 LOGI(
"buffer size: %d", rb_size);
75 result_queue_buffer.
resize(rb_size);
79 if (result_queue.available() < len) {
82 while (result_queue.available() < len) {
83 int read_eff = p_stream->readBytes(buffer.data(), buffer.size());
86 if (read_eff != buffer.size()) {
87 LOGD(
"readBytes %d -> %d", buffer.size(), read_eff);
89 int write_eff = p_transform->write(buffer.data(), read_eff);
90 if (write_eff != read_eff) {
91 LOGE(
"TransformationReader::write %d -> %d", read_eff, write_eff);
95 if (++zero_count > MAX_ZERO_READ_COUNT) {
105 int result_len = min((
int)len, result_queue.available());
106 result_len = result_queue.readBytes(data, result_len);
107 LOGD(
"TransformationReader::readBytes: %d -> %d", (
int)len, result_len);
113 result_queue_buffer.
resize(0);
122 QueueStream<uint8_t> result_queue{result_queue_buffer};
123 Stream* p_stream =
nullptr;
124 Vector<uint8_t> buffer{0};
125 T* p_transform =
nullptr;
127 int result_queue_factor = 5;
133 Print* result = p_transform->getPrint();
134 p_transform->setOutput((
Print&)result_queue);
141 if (out) p_transform->setOutput(*out);
167 virtual void setOutput(AudioOutput& print) {
178 virtual Print* getPrint() {
return p_print; }
180 virtual Stream* getStream() {
return p_stream; }
182 size_t readBytes(uint8_t* data,
size_t len)
override {
183 LOGD(
"ReformatBaseStream::readBytes: %d", (
int)len);
184 return reader.readBytes(data, len);
187 int available()
override {
188 return DEFAULT_BUFFER_SIZE;
191 int availableForWrite()
override {
192 return DEFAULT_BUFFER_SIZE;
195 virtual float getByteFactor() = 0;
197 void end()
override {
214 Stream* p_stream =
nullptr;
215 Print* p_print =
nullptr;
218 if (getStream() !=
nullptr) {
219 reader.
begin(
this, getStream());
238 void setStream(
Print& out) { p_print = &out; }
240 size_t write(
const uint8_t* data,
size_t len) {
241 return p_print->write(data, len);
249 Print* p_print =
nullptr;
263 void setStream(
AudioStream& stream) { p_stream = &stream; }
269 size_t write(
const uint8_t* data,
size_t len)
override {
270 return p_stream->write(data, len);
273 int availableForWrite()
override {
return p_stream->availableForWrite(); }
275 bool begin()
override {
return p_stream->begin(); }
277 void end()
override { p_stream->end(); }
282 operator bool()
override {
return *p_stream; }
285 AudioStream* p_stream =
nullptr;
298 void setOutput(
AudioOutput& stream) { p_stream = &stream; }
304 size_t write(
const uint8_t* data,
size_t len)
override {
305 return p_stream->write(data, len);
308 bool begin()
override {
return p_stream->begin(); }
310 void end()
override { p_stream->end(); }
315 operator bool()
override {
return *p_stream; }
318 AudioOutput* p_stream =
nullptr;
367 vector.push_back(out);
372 vector.push_back(out);
376 for (
int j = 0; j < vector.size(); j++) {
382 for (
int j = 0; j < vector.size(); j++) {
383 vector[j]->setAudioInfo(info);
387 size_t write(
const uint8_t* data,
size_t len)
override {
388 for (
auto& out : vector) {
394 memcpy(copy, data, len);
396 int written = out->write(copy + start, open);
404 size_t write(uint8_t ch)
override {
405 for (
int j = 0; j < vector.size(); j++) {
408 open -= vector[j]->write(ch);
416 for (
auto& tmp : vector) {
417 if (tmp !=
nullptr && tmp->isDeletable()) {
475 start_ms = startSeconds * 1000;
476 calculateByteLimits();
482 calculateByteLimits();
488 end_ms = endSeconds * 1000;
489 calculateByteLimits();
495 calculateByteLimits();
500 if (current_bytes < start_bytes)
return false;
501 if (end_bytes > 0 && current_bytes > end_bytes)
return false;
507 return (current_bytes < end_bytes && current_bytes >= start_bytes);
515 bool begin()
override {
516 calculateByteLimits();
518 LOGI(
"byte range %u - %u", (
unsigned)start_bytes, (
unsigned)end_bytes);
522 operator bool()
override {
return isActive(); }
529 if (p_stream ==
nullptr)
return 0;
531 if (start_bytes > current_bytes) {
532 consumeBytes(start_bytes - current_bytes);
539 result = p_stream->readBytes(data, len);
540 current_bytes += len;
542 }
while (result > 0 && current_bytes < start_bytes);
547 size_t write(
const uint8_t* data,
size_t len)
override {
548 if (current_bytes >= end_bytes)
return 0;
549 current_bytes += len;
550 if (current_bytes < start_bytes)
return len;
551 return p_print->write(data, len);
556 if (p_stream ==
nullptr)
return 0;
557 return current_bytes < end_bytes ? p_stream->available() : 0;
564 calculateByteLimits();
567 int availableForWrite()
override {
568 return current_bytes < end_bytes ? p_print->availableForWrite() : 0;
603 size_t size() {
return end_bytes - start_bytes; }
606 Stream* p_stream =
nullptr;
607 Print* p_print =
nullptr;
608 AudioInfoSupport* p_info =
nullptr;
609 uint32_t start_ms = 0;
610 uint32_t end_ms = UINT32_MAX;
611 uint32_t start_bytes = 0;
612 uint32_t end_bytes = UINT32_MAX;
613 uint32_t current_bytes = 0;
614 float compression_ratio = 1.0;
616 void consumeBytes(uint32_t len) {
618 uint8_t buffer[1024];
620 int toread = min(1024, open);
621 p_stream->readBytes(buffer, toread);
624 current_bytes += len;
625 LOGD(
"consumed %u -> %u", (
unsigned)len, (
unsigned)current_bytes);
628 void calculateByteLimits() {
630 if (bytes_per_second > 0) {
631 start_bytes = bytes_per_second * start_ms / compression_ratio / 1000;
632 end_bytes = bytes_per_second * end_ms / compression_ratio / 1000;
634 LOGE(
"AudioInfo not defined");
657 bool begin()
override {
658 AudioOutput::begin();
660 for (
auto& out : out_channels) {
661 for (
auto& ch : out.channels) {
663 LOGE(
"Channel '%d' not valid for max %d channels", ch, cfg.
channels);
675 channels.push_back(channel);
677 def.channels = channels;
679 def.p_audio_info = &out;
680 out_channels.push_back(def);
687 channels.push_back(channel);
689 def.channels = channels;
691 def.p_audio_info = &out;
692 out_channels.push_back(def);
699 channels.push_back(channel);
701 def.channels = channels;
703 out_channels.push_back(def);
710 channels.push_back(left);
711 channels.push_back(right);
713 def.channels = channels;
715 out_channels.push_back(def);
722 channels.push_back(left);
723 channels.push_back(right);
725 def.channels = channels;
727 def.p_audio_info = &out;
728 out_channels.push_back(def);
735 channels.push_back(left);
736 channels.push_back(right);
738 def.channels = channels;
740 def.p_audio_info = &out;
741 out_channels.push_back(def);
744 size_t write(
const uint8_t* data,
size_t len)
override {
745 if (!is_active)
return false;
746 LOGD(
"write %d", (
int)len);
749 return writeT<int16_t>(data, len);
751 return writeT<int24_t>(data, len);
753 return writeT<int32_t>(data, len);
762 for (
auto& info : out_channels) {
763 auto p_notify = info.p_audio_info;
764 if (p_notify !=
nullptr) {
767 p_notify->setAudioInfo(result);
774 Print* p_out =
nullptr;
781 template <
typename T>
782 size_t writeT(
const uint8_t* buffer,
size_t size) {
783 if (!is_active)
return 0;
784 int sample_count = size /
sizeof(T);
786 T* data = (T*)buffer;
788 for (
int i = 0; i < sample_count; i += cfg.
channels) {
790 for (
auto& out : out_channels) {
791 T out_frame[out.channels.size()];
793 for (
auto& ch : out.channels) {
795 int channel = (ch < cfg.
channels) ? ch : cfg.channels - 1;
796 out_frame[ch_out++] = frame[channel];
799 size_t written = out.buffer.writeArray((
const uint8_t*)&out_frame,
802 if (out.buffer.availableForWrite() <
sizeof(out_frame)) {
803 out.p_out->write(out.buffer.data(), out.buffer.available());
817 for (
auto& channels_select : out_channels) {
818 if (channels_select.p_out == out)
return channels_select.channels.size();
820 return defaultChannels;