3#include "AudioToolsConfig.h"
4#include "AudioTools/CoreAudio/AudioTypes.h"
5#include "AudioTools/CoreAudio/Buffers.h"
6#include "AudioTools/CoreAudio/BaseConverter.h"
7#include "AudioTools/CoreAudio/AudioLogger.h"
8#include "AudioTools/CoreAudio/AudioStreams.h"
9#include "AudioTools/CoreAudio/AudioMetaData/MimeDetector.h"
11#define NOT_ENOUGH_MEMORY_MSG "Could not allocate enough memory: %d bytes"
52 if (p_mime_detector!=
nullptr) {
53 p_mime_detector->begin();
57 LOGI(
"buffer_size=%d",buffer_size);
59 LOGE(NOT_ENOUGH_MEMORY_MSG, buffer_size);
79 this->from_audio = &from;
96 p_converter =
nullptr;
102 p_converter = &converter;
108 LOGD(
"copy %d bytes %s", (
int) bytes, log_name);
109 if (!active)
return 0;
111 if (from==
nullptr && to==
nullptr)
return 0;
117 int to_write = to->availableForWrite();
118 if (check_available_for_write && to_write==0){
124 if (buffer.size() < bytes){
125 LOGI(
"Resize to %d", (
int) bytes);
126 buffer.resize(bytes);
130 size_t delayCount = 0;
132 if (check_available) {
135 size_t bytes_to_read = bytes;
136 size_t bytes_read = 0;
139 bytes_to_read = min(len,
static_cast<size_t>(buffer_size));
142 bytes_to_read = min((
int)bytes_to_read, to_write);
154 if (bytes_to_read>0){
155 bytes_read = from->readBytes((uint8_t*)&buffer[0], bytes_to_read);
159 if (p_mime_detector !=
nullptr){
160 p_mime_detector->
write(buffer.data(), bytes_to_read);
164 if (p_converter!=
nullptr) p_converter->convert((uint8_t*)buffer.data(), bytes_read );
167 result =
write(bytes_read, delayCount);
170 if (onWrite!=
nullptr) onWrite(onWriteObj, &buffer[0], result);
173 LOGI(
"StreamCopy::copy %s %u -> %u -> %u bytes - in %u hops",log_name, (
unsigned int)bytes_to_read,(
unsigned int) bytes_read, (
unsigned int)result, (
unsigned int)delayCount);
180 delay(delay_on_no_data);
187 delay(delay_on_no_data);
188 LOGD(
"no data %s", log_name);
196 if (!active)
return 0;
198 for (
size_t j=0;j<pages;j++){
206 if (!active)
return 0;
212 size_t copyAll(
int retryCount=5,
int retryWaitMs=200){
214 if (!active)
return 0;
218 if (from==
nullptr || to ==
nullptr)
234 if (retry>retryCount){
212 size_t copyAll(
int retryCount=5,
int retryWaitMs=200) {
…}
245 if (availableCallback!=
nullptr){
246 result = availableCallback((
Stream*)from);
248 result = from->available();
251 LOGW(
"source not defined");
253 LOGD(
"available: %d", result);
259 delay_on_no_data = delayMs;
265 this->onWrite = onWrite;
266 this->onWriteObj = obj;
271 availableCallback = callback;
286 check_available_for_write = flag;
291 return check_available_for_write;
296 check_available = flag;
301 return check_available;
307 buffer.resize(buffer_size);
332 if (min_copy_size==0 && from_audio !=
nullptr){
336 return min_copy_size;
341 min_copy_size = size;
346 is_sync_audio_info = active;
351 p_mime_detector = &mime;
359 int buffer_size = DEFAULT_BUFFER_SIZE;
360 void (*onWrite)(
void*obj,
void*buffer,
size_t len) =
nullptr;
361 int (*availableCallback)(Stream*stream)=
nullptr;
362 void *onWriteObj =
nullptr;
363 bool check_available_for_write =
false;
364 bool check_available =
true;
365 int retryLimit = COPY_RETRY_LIMIT;
366 int delay_on_no_data = COPY_DELAY_ON_NODATA;
368 const char* log_name =
"";
369 int retry_delay = 10;
371 int min_copy_size = 1;
372 bool is_sync_audio_info =
false;
373 AudioInfoSupport *p_audio_info_support =
nullptr;
374 BaseConverter* p_converter =
nullptr;
375 MimeDetector* p_mime_detector =
nullptr;
377 void syncAudioInfo(){
379 if (is_sync_audio_info && from_audio !=
nullptr && p_audio_info_support !=
nullptr){
381 AudioInfo info_to = p_audio_info_support->audioInfo();
382 if (info_from != info_to){
383 LOGI(
"--> StreamCopy: ");
384 p_audio_info_support->setAudioInfo(info_from);
390 size_t write(
size_t len,
size_t &delayCount ){
391 if (!buffer || len==0)
return 0;
392 LOGD(
"write: %d", (
int)len);
397 size_t written = to->write((
const uint8_t*)buffer.data()+total, open);
398 LOGD(
"write: %d -> %d", (
int) open, (
int) written);
405 if (written>0) retry = 0;
408 if (retry++ > retryLimit){
409 LOGE(
"write %s to target has failed after %d retries! (%ld bytes)", log_name, retry, open);
416 LOGI(
"try write %s - %d (open %ld bytes) ",log_name, retry, open);
390 size_t write(
size_t len,
size_t &delayCount ) {
…}