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
33 p_transform = transform;
34 if (transform ==
nullptr) {
35 LOGE(
"transform is NULL");
38 if (p_stream ==
nullptr) {
39 LOGE(
"p_stream is NULL");
50 result_queue_buffer.resize(size);
55 size_t readBytes(uint8_t *data,
size_t len) {
56 LOGD(
"TransformationReader::readBytes: %d", (
int)len);
61 if (p_stream ==
nullptr) {
62 LOGE(
"p_stream is NULL");
67 if (buffer.size() == 0) {
68 int size = (0.5f / p_transform->getByteFactor() * len);
71 LOGI(
"read size: %d", size);
75 if (result_queue_buffer.
size() == 0) {
77 int rb_size = len * result_queue_factor;
78 LOGI(
"buffer size: %d", rb_size);
79 result_queue_buffer.resize(rb_size);
83 if (result_queue.available() < len) {
86 while (result_queue.available() < len) {
87 int read_eff = p_stream->readBytes(buffer.data(), buffer.size());
90 if (read_eff != buffer.size()){
91 LOGD(
"readBytes %d -> %d", buffer.size(), read_eff);
93 int write_eff = p_transform->write(buffer.data(), read_eff);
94 if (write_eff != read_eff){
95 LOGE(
"write %d -> %d", read_eff, write_eff);
99 if (++zero_count > MAX_ZERO_READ_COUNT){
109 int result_len = min((
int)len, result_queue.available());
110 result_len = result_queue.readBytes(data, result_len);
111 LOGD(
"TransformationReader::readBytes: %d -> %d", (
int)len,
118 result_queue_buffer.resize(0);
127 QueueStream<uint8_t> result_queue{result_queue_buffer};
128 Stream *p_stream =
nullptr;
129 Vector<uint8_t> buffer{0};
130 T *p_transform =
nullptr;
132 int result_queue_factor = 5;
138 Print *result = p_transform->getPrint();
139 p_transform->setOutput((
Print &)result_queue);
146 if (out) p_transform->setOutput(*out);
172 virtual void setOutput(AudioOutput &print) {
183 virtual Print *getPrint() {
return p_print; }
185 virtual Stream *getStream() {
return p_stream; }
187 size_t readBytes(uint8_t *data,
size_t len)
override {
188 LOGD(
"ReformatBaseStream::readBytes: %d", (
int)len);
189 return reader.readBytes(data, len);
192 int available()
override {
193 return DEFAULT_BUFFER_SIZE;
196 int availableForWrite()
override {
197 return DEFAULT_BUFFER_SIZE;
200 virtual float getByteFactor() = 0;
202 void end()
override {
217 Stream *p_stream =
nullptr;
218 Print *p_print =
nullptr;
221 if (getStream() !=
nullptr) {
222 reader.
begin(
this, getStream());
241 void setStream(
Print& out) { p_print = &out; }
243 size_t write(
const uint8_t *data,
size_t len) {
244 return p_print->write(data, len);
252 Print *p_print =
nullptr;
266 void setStream(
AudioStream &stream) { p_stream = &stream; }
272 size_t write(
const uint8_t *data,
size_t len)
override {
273 return p_stream->write(data, len);
276 int availableForWrite()
override {
return p_stream->availableForWrite(); }
278 bool begin()
override {
return p_stream->begin(); }
280 void end()
override { p_stream->end(); }
285 operator bool()
override {
return *p_stream; }
288 AudioStream *p_stream =
nullptr;
301 void setOutput(
AudioOutput &stream) { p_stream = &stream; }
307 size_t write(
const uint8_t *data,
size_t len)
override {
308 return p_stream->write(data, len);
311 bool begin()
override {
return p_stream->begin(); }
313 void end()
override { p_stream->end(); }
318 operator bool()
override {
return *p_stream; }
321 AudioOutput *p_stream =
nullptr;
362 for (
int j = 0; j < vector.size(); j++) {
376 vector.push_back(out);
381 vector.push_back(out);
385 for (
int j = 0; j < vector.size(); j++) {
391 for (
int j = 0; j < vector.size(); j++) {
392 vector[j]->setAudioInfo(info);
396 size_t write(
const uint8_t *data,
size_t len) {
397 for (
int j = 0; j < vector.size(); j++) {
401 int written = vector[j]->write(data + start, open);
409 size_t write(uint8_t ch) {
410 for (
int j = 0; j < vector.size(); j++) {
413 open -= vector[j]->write(ch);
420 Vector<AudioOutput *> vector;
456 start_ms = startSeconds * 1000;
457 calculateByteLimits();
463 calculateByteLimits();
469 end_ms = endSeconds * 1000;
470 calculateByteLimits();
476 calculateByteLimits();
481 if (current_bytes < start_bytes)
return false;
482 if (end_bytes > 0 && current_bytes > end_bytes)
return false;
488 return (current_bytes < end_bytes && current_bytes >= start_bytes);
496 bool begin()
override {
497 calculateByteLimits();
499 LOGI(
"byte range %u - %u",(
unsigned) start_bytes,(
unsigned) end_bytes);
503 operator bool()
override {
return isActive(); }
510 if (p_stream ==
nullptr)
return 0;
512 if (start_bytes > current_bytes){
513 consumeBytes(start_bytes - current_bytes);
520 result = p_stream->readBytes(data, len);
521 current_bytes += len;
523 }
while (result > 0 && current_bytes < start_bytes);
528 size_t write(
const uint8_t *data,
size_t len)
override {
529 if (current_bytes >= end_bytes)
return 0;
530 current_bytes += len;
531 if (current_bytes < start_bytes)
return len;
532 return p_print->write(data, len);
528 size_t write(
const uint8_t *data,
size_t len)
override {
…}
537 if (p_stream ==
nullptr)
return 0;
538 return current_bytes < end_bytes ? p_stream->available() : 0;
545 calculateByteLimits();
548 int availableForWrite()
override {
549 return current_bytes < end_bytes ? p_print->availableForWrite() : 0;
585 return end_bytes - start_bytes;
589 Stream *p_stream =
nullptr;
590 Print *p_print =
nullptr;
591 AudioInfoSupport *p_info =
nullptr;
592 uint32_t start_ms = 0;
593 uint32_t end_ms = UINT32_MAX;
594 uint32_t start_bytes = 0;
595 uint32_t end_bytes = UINT32_MAX;
596 uint32_t current_bytes = 0;
597 float compression_ratio = 1.0;
599 void consumeBytes(uint32_t len){
601 uint8_t buffer[1024];
603 int toread = min(1024, open);
604 p_stream->readBytes(buffer, toread);
607 current_bytes += len;
608 LOGD(
"consumed %u -> %u",(
unsigned) len, (
unsigned)current_bytes);
611 void calculateByteLimits() {
613 if (bytes_per_second > 0) {
614 start_bytes = bytes_per_second * start_ms / compression_ratio / 1000;
615 end_bytes = bytes_per_second * end_ms / compression_ratio / 1000;
617 LOGE(
"AudioInfo not defined");
640 bool begin()
override {
641 AudioOutput::begin();
643 for (
auto &out : out_channels) {
644 for (
auto &ch : out.channels) {
646 LOGE(
"Channel '%d' not valid for max %d channels", ch, cfg.
channels);
658 channels.push_back(channel);
660 def.channels = channels;
662 def.p_audio_info = &out;
663 out_channels.push_back(def);
670 channels.push_back(channel);
672 def.channels = channels;
674 def.p_audio_info = &out;
675 out_channels.push_back(def);
682 channels.push_back(channel);
684 def.channels = channels;
686 out_channels.push_back(def);
693 channels.push_back(left);
694 channels.push_back(right);
696 def.channels = channels;
698 out_channels.push_back(def);
705 channels.push_back(left);
706 channels.push_back(right);
708 def.channels = channels;
710 def.p_audio_info = &out;
711 out_channels.push_back(def);
718 channels.push_back(left);
719 channels.push_back(right);
721 def.channels = channels;
723 def.p_audio_info = &out;
724 out_channels.push_back(def);
727 size_t write(
const uint8_t *data,
size_t len)
override {
728 if (!is_active)
return false;
729 LOGD(
"write %d", (
int)len);
732 return writeT<int16_t>(data, len);
734 return writeT<int24_t>(data, len);
736 return writeT<int32_t>(data, len);
745 for (
auto &info : out_channels) {
746 auto p_notify = info.p_audio_info;
747 if (p_notify !=
nullptr) {
750 p_notify->setAudioInfo(result);
757 Print *p_out =
nullptr;
764 template <
typename T>
765 size_t writeT(
const uint8_t *buffer,
size_t size) {
766 if (!is_active)
return 0;
767 int sample_count = size /
sizeof(T);
769 T *data = (T *)buffer;
771 for (
int i = 0; i < sample_count; i += cfg.
channels) {
773 for (
auto &out : out_channels) {
774 T out_frame[out.channels.size()];
776 for (
auto &ch : out.channels) {
778 int channel = (ch < cfg.
channels) ? ch : cfg.channels - 1;
779 out_frame[ch_out++] = frame[channel];
782 size_t written = out.buffer.writeArray((
const uint8_t *)&out_frame,
sizeof(out_frame));
784 if (out.buffer.availableForWrite()<
sizeof(out_frame)){
785 out.p_out->write(out.buffer.data(), out.buffer.available());
798 for (
auto &channels_select : out_channels) {
799 if (channels_select.p_out == out)
return channels_select.channels.size();
801 return defaultChannels;