diff --git a/_audio_player_8h_source.html b/_audio_player_8h_source.html index c3d8fc781..1b5097465 100644 --- a/_audio_player_8h_source.html +++ b/_audio_player_8h_source.html @@ -575,12 +575,12 @@
audio_tools::MetaDataID3::write
virtual size_t write(const uint8_t *data, size_t len)
Provide tha audio data to the API to parse for Meta Data.
Definition: MetaDataID3.h:579
audio_tools::Print
Definition: NoArduino.h:58
audio_tools::StreamCopyT< uint8_t >
-
audio_tools::StreamCopyT::copyBytes
size_t copyBytes(size_t bytes)
copies the inicated number of bytes from the source to the destination and returns the processed numb...
Definition: StreamCopy.h:101
-
audio_tools::StreamCopyT::resize
void resize(int len)
resizes the copy buffer
Definition: StreamCopy.h:308
-
audio_tools::StreamCopyT::setCallbackOnWrite
void setCallbackOnWrite(void(*onWrite)(void *obj, void *buffer, size_t len), void *obj)
Defines a callback that is notified with the wirtten data.
Definition: StreamCopy.h:266
-
audio_tools::StreamCopyT::begin
void begin()
(Re)starts the processing
Definition: StreamCopy.h:45
-
audio_tools::StreamCopyT::bufferSize
int bufferSize()
Provides the buffer size.
Definition: StreamCopy.h:283
-
audio_tools::StreamCopyT::copy
size_t copy()
copies the data from the source to the destination and returns the processed number of bytes
Definition: StreamCopy.h:89
+
audio_tools::StreamCopyT::copyBytes
size_t copyBytes(size_t bytes)
copies the inicated number of bytes from the source to the destination and returns the processed numb...
Definition: StreamCopy.h:108
+
audio_tools::StreamCopyT::resize
void resize(int len)
resizes the copy buffer
Definition: StreamCopy.h:315
+
audio_tools::StreamCopyT::setCallbackOnWrite
void setCallbackOnWrite(void(*onWrite)(void *obj, void *buffer, size_t len), void *obj)
Defines a callback that is notified with the wirtten data.
Definition: StreamCopy.h:273
+
audio_tools::StreamCopyT::begin
void begin()
(Re)starts the processing
Definition: StreamCopy.h:49
+
audio_tools::StreamCopyT::bufferSize
int bufferSize()
Provides the buffer size.
Definition: StreamCopy.h:290
+
audio_tools::StreamCopyT::copy
size_t copy()
copies the data from the source to the destination and returns the processed number of bytes
Definition: StreamCopy.h:96
audio_tools::Stream
Definition: NoArduino.h:125
audio_tools::VolumeControl
Abstract class for handling of the linear input volume to determine the multiplication factor which s...
Definition: VolumeControl.h:17
audio_tools::VolumeStream
Adjust the volume of the related input or output: To work properly the class needs to know the bits p...
Definition: VolumeStream.h:34
@@ -591,7 +591,7 @@
audio_tools::VolumeSupport
Supports the setting and getting of the volume.
Definition: AudioTypes.h:207
audio_tools::ID3TypeSelection
ID3TypeSelection
Enum to filter by type of metadata.
Definition: AbstractMetaData.h:8
audio_tools::MetaDataType
MetaDataType
Type of meta info.
Definition: AbstractMetaData.h:11
-
audio_tools::StreamCopy
StreamCopyT< uint8_t > StreamCopy
We provide the typeless StreamCopy.
Definition: StreamCopy.h:453
+
audio_tools::StreamCopy
StreamCopyT< uint8_t > StreamCopy
We provide the typeless StreamCopy.
Definition: StreamCopy.h:460
audio_tools
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:868
audio_tools::millis
uint32_t millis()
Returns the milliseconds since the start.
Definition: Time.h:12
audio_tools::AudioInfo
Basic Audio information which drives e.g. I2S.
Definition: AudioTypes.h:52
diff --git a/_audio_server_8h_source.html b/_audio_server_8h_source.html index 5a705f5b3..2b602077c 100644 --- a/_audio_server_8h_source.html +++ b/_audio_server_8h_source.html @@ -451,7 +451,7 @@
501 #endif
AudioTools.h
stop
void stop()
Public generic methods.
Definition: AudioRuntime.h:27
-
audio_tools::StreamCopy
StreamCopyT< uint8_t > StreamCopy
We provide the typeless StreamCopy.
Definition: StreamCopy.h:453
+
audio_tools::StreamCopy
StreamCopyT< uint8_t > StreamCopy
We provide the typeless StreamCopy.
Definition: StreamCopy.h:460
audio_tools
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:868
diff --git a/_h_l_s_stream_8h_source.html b/_h_l_s_stream_8h_source.html index c29f3523a..074a7a3f7 100644 --- a/_h_l_s_stream_8h_source.html +++ b/_h_l_s_stream_8h_source.html @@ -766,8 +766,8 @@
audio_tools::StrView::length
virtual int length()
Definition: StrView.h:383
audio_tools::StrView::c_str
virtual const char * c_str()
provides the string value as const char*
Definition: StrView.h:379
audio_tools::StreamCopyT< uint8_t >
-
audio_tools::StreamCopyT::copyAll
size_t copyAll(int retryCount=5, int retryWaitMs=200)
copies all data - returns the number of processed bytes
Definition: StreamCopy.h:204
-
audio_tools::StreamCopyT::begin
void begin()
(Re)starts the processing
Definition: StreamCopy.h:45
+
audio_tools::StreamCopyT::copyAll
size_t copyAll(int retryCount=5, int retryWaitMs=200)
copies all data - returns the number of processed bytes
Definition: StreamCopy.h:211
+
audio_tools::StreamCopyT::begin
void begin()
(Re)starts the processing
Definition: StreamCopy.h:49
audio_tools::URLHistory
Definition: HLSStream.h:244
audio_tools::URLLoaderHLSBase
Abstract API for URLLoaderHLS.
Definition: HLSStream.h:17
audio_tools::URLLoaderHLS
Definition: HLSStream.h:67
diff --git a/_stream_copy_8h_source.html b/_stream_copy_8h_source.html index a30fa3d33..c4e55c4e1 100644 --- a/_stream_copy_8h_source.html +++ b/_stream_copy_8h_source.html @@ -104,379 +104,386 @@
41  begin();
42  }
43 
-
45  void begin(){
-
46  TRACED();
-
47  is_first = true;
-
48  resize(buffer_size);
-
49  if (buffer){
-
50  LOGI("buffer_size=%d",buffer_size);
-
51  } else {
-
52  LOGE(NOT_ENOUGH_MEMORY_MSG, buffer_size);
-
53  }
-
54  }
-
55 
-
57  void end() {
-
58  if (is_cleanup_from) delete this->from;
-
59  this->from = nullptr;
-
60  this->to = nullptr;
-
61  }
-
62 
-
64  void begin(Print &to, Stream &from){
-
65  is_cleanup_from = true;
-
66  this->from = new AudioStreamWrapper(from);
-
67  this->to = &to;
-
68  begin();
-
69  }
-
70 
-
72  void begin(Print &to, AudioStream &from){
-
73  this->from = &from;
+
44  ~StreamCopyT() {
+
45  end();
+
46  }
+
47 
+
49  void begin(){
+
50  TRACED();
+
51  is_first = true;
+
52  resize(buffer_size);
+
53  if (buffer){
+
54  LOGI("buffer_size=%d",buffer_size);
+
55  } else {
+
56  LOGE(NOT_ENOUGH_MEMORY_MSG, buffer_size);
+
57  }
+
58  }
+
59 
+
61  void end() {
+
62  if (is_cleanup_from) {
+
63  delete this->from;
+
64  is_cleanup_from = false;
+
65  }
+
66  this->from = nullptr;
+
67  this->to = nullptr;
+
68  }
+
69 
+
71  void begin(Print &to, Stream &from){
+
72  is_cleanup_from = true;
+
73  this->from = new AudioStreamWrapper(from);
74  this->to = &to;
75  begin();
76  }
77 
-
79  Stream *getFrom(){
-
80  return from;
-
81  }
-
82 
-
84  Print *getTo() {
-
85  return to;
-
86  }
-
87 
-
89  inline size_t copy() {
-
90  p_converter = nullptr;
-
91  return copyBytes(buffer_size);
-
92  }
-
93 
-
95  inline size_t copy(BaseConverter &converter) {
-
96  p_converter = &converter;
-
97  return copyBytes(buffer_size);
-
98  }
-
99 
-
101  inline size_t copyBytes(size_t bytes){
-
102  LOGD("copy %d bytes %s", (int) bytes, log_name);
-
103  if (!active) return 0;
-
104  // if not initialized we do nothing
-
105  if (from==nullptr && to==nullptr) return 0;
+
79  void begin(Print &to, AudioStream &from){
+
80  this->from = &from;
+
81  this->to = &to;
+
82  begin();
+
83  }
+
84 
+
86  Stream *getFrom(){
+
87  return from;
+
88  }
+
89 
+
91  Print *getTo() {
+
92  return to;
+
93  }
+
94 
+
96  inline size_t copy() {
+
97  p_converter = nullptr;
+
98  return copyBytes(buffer_size);
+
99  }
+
100 
+
102  inline size_t copy(BaseConverter &converter) {
+
103  p_converter = &converter;
+
104  return copyBytes(buffer_size);
+
105  }
106 
-
107  // synchronize AudioInfo
-
108  syncAudioInfo();
-
109 
-
110  // E.g. if we try to write to a server we might not have any output destination yet
-
111  int to_write = to->availableForWrite();
-
112  if (check_available_for_write && to_write==0){
-
113  delay(500);
-
114  return 0;
-
115  }
+
108  inline size_t copyBytes(size_t bytes){
+
109  LOGD("copy %d bytes %s", (int) bytes, log_name);
+
110  if (!active) return 0;
+
111  // if not initialized we do nothing
+
112  if (from==nullptr && to==nullptr) return 0;
+
113 
+
114  // synchronize AudioInfo
+
115  syncAudioInfo();
116 
-
117  // resize copy buffer if necessary
-
118  if (buffer.size() < bytes){
-
119  LOGI("Resize to %d", (int) bytes);
-
120  buffer.resize(bytes);
-
121  }
-
122 
-
123  size_t result = 0;
-
124  size_t delayCount = 0;
-
125  size_t len = bytes;
-
126  if (check_available) {
-
127  len = available();
+
117  // E.g. if we try to write to a server we might not have any output destination yet
+
118  int to_write = to->availableForWrite();
+
119  if (check_available_for_write && to_write==0){
+
120  delay(500);
+
121  return 0;
+
122  }
+
123 
+
124  // resize copy buffer if necessary
+
125  if (buffer.size() < bytes){
+
126  LOGI("Resize to %d", (int) bytes);
+
127  buffer.resize(bytes);
128  }
-
129  size_t bytes_to_read = bytes;
-
130  size_t bytes_read = 0;
-
131 
-
132  if (len > 0){
-
133  bytes_to_read = min(len, static_cast<size_t>(buffer_size));
-
134  // don't overflow buffer
-
135  if (to_write > 0){
-
136  bytes_to_read = min((int)bytes_to_read, to_write);
-
137  }
+
129 
+
130  size_t result = 0;
+
131  size_t delayCount = 0;
+
132  size_t len = bytes;
+
133  if (check_available) {
+
134  len = available();
+
135  }
+
136  size_t bytes_to_read = bytes;
+
137  size_t bytes_read = 0;
138 
-
139  // round to full frames
-
140  int copy_size = minCopySize();
-
141  if (copy_size > 0){
-
142  size_t samples = bytes_to_read / minCopySize();
-
143  bytes_to_read = samples * minCopySize();
+
139  if (len > 0){
+
140  bytes_to_read = min(len, static_cast<size_t>(buffer_size));
+
141  // don't overflow buffer
+
142  if (to_write > 0){
+
143  bytes_to_read = min((int)bytes_to_read, to_write);
144  }
145 
-
146  // get the data now
-
147  bytes_read = 0;
-
148  if (bytes_to_read>0){
-
149  bytes_read = from->readBytes((uint8_t*)&buffer[0], bytes_to_read);
-
150  }
-
151 
-
152  // determine mime
-
153  notifyMime(buffer.data(), bytes_to_read);
-
154 
-
155  // convert data
-
156  if (p_converter!=nullptr) p_converter->convert((uint8_t*)buffer.data(), result );
-
157 
-
158  // write data
-
159  result = write(bytes_read, delayCount);
-
160 
-
161  // callback with unconverted data
-
162  if (onWrite!=nullptr) onWrite(onWriteObj, &buffer[0], result);
-
163 
-
164  #ifndef COPY_LOG_OFF
-
165  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);
-
166  #endif
-
167  //TRACED();
-
168 
-
169  if (result == 0){
-
170  TRACED();
-
171  // give the processor some time
-
172  delay(delay_on_no_data);
-
173  }
-
174 
-
175  //TRACED();
-
176  CHECK_MEMORY();
-
177  } else {
-
178  // give the processor some time
-
179  delay(delay_on_no_data);
-
180  LOGD("no data %s", log_name);
-
181  }
-
182  //TRACED();
-
183  return result;
-
184  }
-
185 
-
187  size_t copyN(size_t pages){
-
188  if (!active) return 0;
-
189  size_t total=0;
-
190  for (size_t j=0;j<pages;j++){
-
191  total+=copy();
-
192  }
-
193  return total;
-
194  }
-
195 
-
197  size_t copyMs(size_t millis, AudioInfo info){
-
198  if (!active) return 0;
-
199  size_t pages = AudioTime::toBytes(millis, info) / buffer_size;
-
200  return copyN(pages);
+
146  // round to full frames
+
147  int copy_size = minCopySize();
+
148  if (copy_size > 0){
+
149  size_t samples = bytes_to_read / minCopySize();
+
150  bytes_to_read = samples * minCopySize();
+
151  }
+
152 
+
153  // get the data now
+
154  bytes_read = 0;
+
155  if (bytes_to_read>0){
+
156  bytes_read = from->readBytes((uint8_t*)&buffer[0], bytes_to_read);
+
157  }
+
158 
+
159  // determine mime
+
160  notifyMime(buffer.data(), bytes_to_read);
+
161 
+
162  // convert data
+
163  if (p_converter!=nullptr) p_converter->convert((uint8_t*)buffer.data(), result );
+
164 
+
165  // write data
+
166  result = write(bytes_read, delayCount);
+
167 
+
168  // callback with unconverted data
+
169  if (onWrite!=nullptr) onWrite(onWriteObj, &buffer[0], result);
+
170 
+
171  #ifndef COPY_LOG_OFF
+
172  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);
+
173  #endif
+
174  //TRACED();
+
175 
+
176  if (result == 0){
+
177  TRACED();
+
178  // give the processor some time
+
179  delay(delay_on_no_data);
+
180  }
+
181 
+
182  //TRACED();
+
183  CHECK_MEMORY();
+
184  } else {
+
185  // give the processor some time
+
186  delay(delay_on_no_data);
+
187  LOGD("no data %s", log_name);
+
188  }
+
189  //TRACED();
+
190  return result;
+
191  }
+
192 
+
194  size_t copyN(size_t pages){
+
195  if (!active) return 0;
+
196  size_t total=0;
+
197  for (size_t j=0;j<pages;j++){
+
198  total+=copy();
+
199  }
+
200  return total;
201  }
202 
-
204  size_t copyAll(int retryCount=5, int retryWaitMs=200){
-
205  TRACED();
-
206  if (!active) return 0;
-
207  size_t result = 0;
-
208  int retry = 0;
+
204  size_t copyMs(size_t millis, AudioInfo info){
+
205  if (!active) return 0;
+
206  size_t pages = AudioTime::toBytes(millis, info) / buffer_size;
+
207  return copyN(pages);
+
208  }
209 
-
210  if (from==nullptr || to == nullptr)
-
211  return result;
-
212 
-
213  // copy while source has data available
-
214  int count=0;
-
215  while (true){
-
216  count = copy();
-
217  result += count;
-
218  if (count==0){
-
219  // wait for more data
-
220  retry++;
-
221  delay(retryWaitMs);
-
222  } else {
-
223  retry = 0; // after we got new data we restart the counting
-
224  }
-
225  // stop the processing if we passed the retry limit
-
226  if (retry>retryCount){
-
227  break;
-
228  }
-
229  }
-
230  return result;
-
231  }
-
232 
-
234  int available() {
-
235  int result = 0;
-
236  if (from!=nullptr) {
-
237  if (availableCallback!=nullptr){
-
238  result = availableCallback((Stream*)from);
-
239  } else {
-
240  result = from->available();
-
241  }
-
242  } else {
-
243  LOGW("source not defined");
-
244  }
-
245  LOGD("available: %d", result);
-
246  return result;
-
247  }
-
248 
-
250  void setDelayOnNoData(int delayMs){
-
251  delay_on_no_data = delayMs;
-
252  }
-
253 
-
255  const char* mime() {
-
256  return actual_mime;
-
257  }
-
258 
-
260  void setMimeCallback(void (*callback)(const char*)){
-
261  TRACED();
-
262  this->notifyMimeCallback = callback;
-
263  }
-
264 
-
266  void setCallbackOnWrite(void (*onWrite)(void*obj, void*buffer, size_t len), void* obj){
-
267  TRACED();
-
268  this->onWrite = onWrite;
-
269  this->onWriteObj = obj;
+
211  size_t copyAll(int retryCount=5, int retryWaitMs=200){
+
212  TRACED();
+
213  if (!active) return 0;
+
214  size_t result = 0;
+
215  int retry = 0;
+
216 
+
217  if (from==nullptr || to == nullptr)
+
218  return result;
+
219 
+
220  // copy while source has data available
+
221  int count=0;
+
222  while (true){
+
223  count = copy();
+
224  result += count;
+
225  if (count==0){
+
226  // wait for more data
+
227  retry++;
+
228  delay(retryWaitMs);
+
229  } else {
+
230  retry = 0; // after we got new data we restart the counting
+
231  }
+
232  // stop the processing if we passed the retry limit
+
233  if (retry>retryCount){
+
234  break;
+
235  }
+
236  }
+
237  return result;
+
238  }
+
239 
+
241  int available() {
+
242  int result = 0;
+
243  if (from!=nullptr) {
+
244  if (availableCallback!=nullptr){
+
245  result = availableCallback((Stream*)from);
+
246  } else {
+
247  result = from->available();
+
248  }
+
249  } else {
+
250  LOGW("source not defined");
+
251  }
+
252  LOGD("available: %d", result);
+
253  return result;
+
254  }
+
255 
+
257  void setDelayOnNoData(int delayMs){
+
258  delay_on_no_data = delayMs;
+
259  }
+
260 
+
262  const char* mime() {
+
263  return actual_mime;
+
264  }
+
265 
+
267  void setMimeCallback(void (*callback)(const char*)){
+
268  TRACED();
+
269  this->notifyMimeCallback = callback;
270  }
271 
-
273  void setAvailableCallback(int (*callback)(Stream*stream)){
-
274  availableCallback = callback;
-
275  }
-
276 
-
278  void setRetry(int retry){
-
279  retryLimit = retry;
-
280  }
-
281 
-
283  int bufferSize() {
-
284  return buffer_size;
-
285  }
-
286 
-
288  void setCheckAvailableForWrite(bool flag){
-
289  check_available_for_write = flag;
-
290  }
-
291 
-
293  bool isCheckAvailableForWrite() {
-
294  return check_available_for_write;
-
295  }
-
296 
-
298  void setCheckAvailable(bool flag){
-
299  check_available = flag;
-
300  }
-
301 
-
303  bool isCheckAvailable() {
-
304  return check_available;
-
305  }
-
306 
-
308  void resize(int len){
-
309  buffer_size = len;
-
310  buffer.resize(buffer_size);
-
311  }
-
312 
-
314  void setActive(bool flag){
-
315  active = flag;
-
316  }
-
317 
-
319  bool isActive(){
-
320  return active;
-
321  }
-
322 
-
324  void setLogName(const char* name){
-
325  log_name = name;
-
326  }
-
327 
-
329  void setRetryDelay(int delay){
-
330  retry_delay = delay;
-
331  }
-
332 
-
334  int minCopySize() {
-
335  if (min_copy_size==0){
-
336  AudioInfo info = from->audioInfoOut();
-
337  min_copy_size = info.bits_per_sample / 8 * info.channels;
-
338  }
-
339  return min_copy_size;
-
340  }
-
341 
-
343  void setMinCopySize(int size){
-
344  min_copy_size = size;
-
345  }
-
346 
-
348  void setSynchAudioInfo(bool active){
-
349  is_sync_audio_info = active;
-
350  }
-
351 
-
352  protected:
-
353  AudioStream *from = nullptr;
-
354  Print *to = nullptr;
-
355  Vector<uint8_t> buffer{0};
-
356  int buffer_size = DEFAULT_BUFFER_SIZE;
-
357  void (*onWrite)(void*obj, void*buffer, size_t len) = nullptr;
-
358  void (*notifyMimeCallback)(const char*mime) = nullptr;
-
359  int (*availableCallback)(Stream*stream)=nullptr;
-
360  void *onWriteObj = nullptr;
-
361  bool is_first = false;
-
362  bool is_cleanup_from = false;
-
363  bool check_available_for_write = false;
-
364  bool check_available = true;
-
365  const char* actual_mime = nullptr;
-
366  int retryLimit = COPY_RETRY_LIMIT;
-
367  int delay_on_no_data = COPY_DELAY_ON_NODATA;
-
368  bool active = true;
-
369  const char* log_name = "";
-
370  int retry_delay = 10;
-
371  int channels = 0;
-
372  int min_copy_size = 1;
-
373  bool is_sync_audio_info = false;
-
374  AudioInfoSupport *p_audio_info_support = nullptr;
-
375  BaseConverter* p_converter = nullptr;
-
376 
-
377 
-
378  void syncAudioInfo(){
-
379  // synchronize audio info
-
380  if (is_sync_audio_info && from != nullptr && p_audio_info_support != nullptr){
-
381  AudioInfo info_from = from->audioInfoOut();
-
382  AudioInfo info_to = p_audio_info_support->audioInfo();
-
383  if (info_from != info_to){
-
384  LOGI("--> StreamCopy: ");
-
385  p_audio_info_support->setAudioInfo(info_from);
-
386  }
-
387  }
-
388  }
-
389 
-
391  size_t write(size_t len, size_t &delayCount ){
-
392  if (!buffer || len==0) return 0;
-
393  LOGD("write: %d", (int)len);
-
394  size_t total = 0;
-
395  long open = len;
-
396  int retry = 0;
-
397  while(open > 0){
-
398  size_t written = to->write((const uint8_t*)buffer.data()+total, open);
-
399  LOGD("write: %d -> %d", (int) open, (int) written);
-
400  total += written;
-
401  open -= written;
-
402  delayCount++;
-
403 
-
404  if (open > 0){
-
405  // if we still have progress we reset the retry counter
-
406  if (written>0) retry = 0;
-
407 
-
408  // abort if we reached the retry limit
-
409  if (retry++ > retryLimit){
-
410  LOGE("write %s to target has failed after %d retries! (%ld bytes)", log_name, retry, open);
-
411  break;
-
412  }
-
413 
-
414  // wait a bit
-
415  if (retry>1) {
-
416  delay(retry_delay);
-
417  LOGI("try write %s - %d (open %ld bytes) ",log_name, retry, open);
-
418  }
-
419  }
-
420 
-
421  CHECK_MEMORY();
-
422  }
-
423  return total;
-
424  }
-
425 
-
427  void notifyMime(void* data, size_t len){
-
428  if (is_first && len>4) {
-
429  const uint8_t *start = (const uint8_t *) data;
-
430  actual_mime = "audio/basic";
-
431  if (start[0]==0xFF && start[1]==0xF1){
-
432  actual_mime = "audio/aac";
-
433  } else if (memcmp(start,"ID3",3) || start[0]==0xFF || start[0]==0xFE ){
-
434  actual_mime = "audio/mpeg";
-
435  } else if (memcmp(start,"RIFF",4)){
-
436  actual_mime = "audio/vnd.wave";
-
437  }
-
438  if (notifyMimeCallback!=nullptr){
-
439  notifyMimeCallback(actual_mime);
-
440  }
-
441  }
-
442  is_first = false;
-
443  }
-
444 
-
445 };
-
446 
-
453 using StreamCopy = StreamCopyT<uint8_t>;
-
454 
-
455 
-
456 } // Namespace
+
273  void setCallbackOnWrite(void (*onWrite)(void*obj, void*buffer, size_t len), void* obj){
+
274  TRACED();
+
275  this->onWrite = onWrite;
+
276  this->onWriteObj = obj;
+
277  }
+
278 
+
280  void setAvailableCallback(int (*callback)(Stream*stream)){
+
281  availableCallback = callback;
+
282  }
+
283 
+
285  void setRetry(int retry){
+
286  retryLimit = retry;
+
287  }
+
288 
+
290  int bufferSize() {
+
291  return buffer_size;
+
292  }
+
293 
+
295  void setCheckAvailableForWrite(bool flag){
+
296  check_available_for_write = flag;
+
297  }
+
298 
+
300  bool isCheckAvailableForWrite() {
+
301  return check_available_for_write;
+
302  }
+
303 
+
305  void setCheckAvailable(bool flag){
+
306  check_available = flag;
+
307  }
+
308 
+
310  bool isCheckAvailable() {
+
311  return check_available;
+
312  }
+
313 
+
315  void resize(int len){
+
316  buffer_size = len;
+
317  buffer.resize(buffer_size);
+
318  }
+
319 
+
321  void setActive(bool flag){
+
322  active = flag;
+
323  }
+
324 
+
326  bool isActive(){
+
327  return active;
+
328  }
+
329 
+
331  void setLogName(const char* name){
+
332  log_name = name;
+
333  }
+
334 
+
336  void setRetryDelay(int delay){
+
337  retry_delay = delay;
+
338  }
+
339 
+
341  int minCopySize() {
+
342  if (min_copy_size==0){
+
343  AudioInfo info = from->audioInfoOut();
+
344  min_copy_size = info.bits_per_sample / 8 * info.channels;
+
345  }
+
346  return min_copy_size;
+
347  }
+
348 
+
350  void setMinCopySize(int size){
+
351  min_copy_size = size;
+
352  }
+
353 
+
355  void setSynchAudioInfo(bool active){
+
356  is_sync_audio_info = active;
+
357  }
+
358 
+
359  protected:
+
360  AudioStream *from = nullptr;
+
361  Print *to = nullptr;
+
362  Vector<uint8_t> buffer{0};
+
363  int buffer_size = DEFAULT_BUFFER_SIZE;
+
364  void (*onWrite)(void*obj, void*buffer, size_t len) = nullptr;
+
365  void (*notifyMimeCallback)(const char*mime) = nullptr;
+
366  int (*availableCallback)(Stream*stream)=nullptr;
+
367  void *onWriteObj = nullptr;
+
368  bool is_first = false;
+
369  bool is_cleanup_from = false;
+
370  bool check_available_for_write = false;
+
371  bool check_available = true;
+
372  const char* actual_mime = nullptr;
+
373  int retryLimit = COPY_RETRY_LIMIT;
+
374  int delay_on_no_data = COPY_DELAY_ON_NODATA;
+
375  bool active = true;
+
376  const char* log_name = "";
+
377  int retry_delay = 10;
+
378  int channels = 0;
+
379  int min_copy_size = 1;
+
380  bool is_sync_audio_info = false;
+
381  AudioInfoSupport *p_audio_info_support = nullptr;
+
382  BaseConverter* p_converter = nullptr;
+
383 
+
384 
+
385  void syncAudioInfo(){
+
386  // synchronize audio info
+
387  if (is_sync_audio_info && from != nullptr && p_audio_info_support != nullptr){
+
388  AudioInfo info_from = from->audioInfoOut();
+
389  AudioInfo info_to = p_audio_info_support->audioInfo();
+
390  if (info_from != info_to){
+
391  LOGI("--> StreamCopy: ");
+
392  p_audio_info_support->setAudioInfo(info_from);
+
393  }
+
394  }
+
395  }
+
396 
+
398  size_t write(size_t len, size_t &delayCount ){
+
399  if (!buffer || len==0) return 0;
+
400  LOGD("write: %d", (int)len);
+
401  size_t total = 0;
+
402  long open = len;
+
403  int retry = 0;
+
404  while(open > 0){
+
405  size_t written = to->write((const uint8_t*)buffer.data()+total, open);
+
406  LOGD("write: %d -> %d", (int) open, (int) written);
+
407  total += written;
+
408  open -= written;
+
409  delayCount++;
+
410 
+
411  if (open > 0){
+
412  // if we still have progress we reset the retry counter
+
413  if (written>0) retry = 0;
+
414 
+
415  // abort if we reached the retry limit
+
416  if (retry++ > retryLimit){
+
417  LOGE("write %s to target has failed after %d retries! (%ld bytes)", log_name, retry, open);
+
418  break;
+
419  }
+
420 
+
421  // wait a bit
+
422  if (retry>1) {
+
423  delay(retry_delay);
+
424  LOGI("try write %s - %d (open %ld bytes) ",log_name, retry, open);
+
425  }
+
426  }
+
427 
+
428  CHECK_MEMORY();
+
429  }
+
430  return total;
+
431  }
+
432 
+
434  void notifyMime(void* data, size_t len){
+
435  if (is_first && len>4) {
+
436  const uint8_t *start = (const uint8_t *) data;
+
437  actual_mime = "audio/basic";
+
438  if (start[0]==0xFF && start[1]==0xF1){
+
439  actual_mime = "audio/aac";
+
440  } else if (memcmp(start,"ID3",3) || start[0]==0xFF || start[0]==0xFE ){
+
441  actual_mime = "audio/mpeg";
+
442  } else if (memcmp(start,"RIFF",4)){
+
443  actual_mime = "audio/vnd.wave";
+
444  }
+
445  if (notifyMimeCallback!=nullptr){
+
446  notifyMimeCallback(actual_mime);
+
447  }
+
448  }
+
449  is_first = false;
+
450  }
+
451 
+
452 };
+
453 
+
460 using StreamCopy = StreamCopyT<uint8_t>;
+
461 
+
462 
+
463 } // Namespace
audio_tools::AudioInfoSupport::audioInfoOut
virtual AudioInfo audioInfoOut()
provides the actual output AudioInfo: this is usually the same as audioInfo() unless we use a transfo...
Definition: AudioTypes.h:146
audio_tools::AudioStream
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition: BaseStream.h:109
audio_tools::AudioStreamWrapper
To be used to support implementations where the readBytes is not virtual.
Definition: AudioStreams.h:24
@@ -484,40 +491,40 @@
audio_tools::BaseConverter
Abstract Base class for Converters A converter is processing the data in the indicated array.
Definition: BaseConverter.h:24
audio_tools::Print
Definition: NoArduino.h:58
audio_tools::StreamCopyT
Typed Stream Copy which supports the conversion from channel to 2 channels. We make sure that we allw...
Definition: StreamCopy.h:23
-
audio_tools::StreamCopyT::setCheckAvailable
void setCheckAvailable(bool flag)
Activates the check that we copy only if available returns a value.
Definition: StreamCopy.h:298
-
audio_tools::StreamCopyT::copyMs
size_t copyMs(size_t millis, AudioInfo info)
Copies audio for the indicated number of milliseconds: note that the resolution is determined by the ...
Definition: StreamCopy.h:197
-
audio_tools::StreamCopyT::setMinCopySize
void setMinCopySize(int size)
Defines the minimum frame size that is used to round the copy size: 0 will automatically try to deter...
Definition: StreamCopy.h:343
-
audio_tools::StreamCopyT::minCopySize
int minCopySize()
Determine frame size.
Definition: StreamCopy.h:334
-
audio_tools::StreamCopyT::copy
size_t copy(BaseConverter &converter)
copies the data from the source to the destination and applies the converter - the result is the proc...
Definition: StreamCopy.h:95
-
audio_tools::StreamCopyT::mime
const char * mime()
Provides the actual mime type, that was determined from the first available data.
Definition: StreamCopy.h:255
-
audio_tools::StreamCopyT::copyBytes
size_t copyBytes(size_t bytes)
copies the inicated number of bytes from the source to the destination and returns the processed numb...
Definition: StreamCopy.h:101
-
audio_tools::StreamCopyT::write
size_t write(size_t len, size_t &delayCount)
blocking write - until everything is processed
Definition: StreamCopy.h:391
-
audio_tools::StreamCopyT::available
int available()
available bytes of the data source
Definition: StreamCopy.h:234
-
audio_tools::StreamCopyT::resize
void resize(int len)
resizes the copy buffer
Definition: StreamCopy.h:308
-
audio_tools::StreamCopyT::setRetry
void setRetry(int retry)
Defines the max number of retries.
Definition: StreamCopy.h:278
-
audio_tools::StreamCopyT::copyN
size_t copyN(size_t pages)
Copies pages * buffersize samples: returns the processed number of bytes.
Definition: StreamCopy.h:187
-
audio_tools::StreamCopyT::setCallbackOnWrite
void setCallbackOnWrite(void(*onWrite)(void *obj, void *buffer, size_t len), void *obj)
Defines a callback that is notified with the wirtten data.
Definition: StreamCopy.h:266
-
audio_tools::StreamCopyT::setRetryDelay
void setRetryDelay(int delay)
Defines the delay that is added before we retry an incomplete copy.
Definition: StreamCopy.h:329
-
audio_tools::StreamCopyT::setSynchAudioInfo
void setSynchAudioInfo(bool active)
Activate the synchronization from the AudioInfo form the source to the target.
Definition: StreamCopy.h:348
-
audio_tools::StreamCopyT::setDelayOnNoData
void setDelayOnNoData(int delayMs)
Defines the dealy that is used if no data is available.
Definition: StreamCopy.h:250
-
audio_tools::StreamCopyT::getFrom
Stream * getFrom()
Provides a pointer to the copy source. Can be used to check if the source is defined.
Definition: StreamCopy.h:79
-
audio_tools::StreamCopyT::copyAll
size_t copyAll(int retryCount=5, int retryWaitMs=200)
copies all data - returns the number of processed bytes
Definition: StreamCopy.h:204
-
audio_tools::StreamCopyT::notifyMime
void notifyMime(void *data, size_t len)
Update the mime type.
Definition: StreamCopy.h:427
-
audio_tools::StreamCopyT::isCheckAvailable
bool isCheckAvailable()
Is Available check activated ?
Definition: StreamCopy.h:303
-
audio_tools::StreamCopyT::isActive
bool isActive()
Check if copier is active.
Definition: StreamCopy.h:319
-
audio_tools::StreamCopyT::begin
void begin(Print &to, Stream &from)
assign a new output and input stream
Definition: StreamCopy.h:64
-
audio_tools::StreamCopyT::end
void end()
Ends the processing.
Definition: StreamCopy.h:57
-
audio_tools::StreamCopyT::begin
void begin()
(Re)starts the processing
Definition: StreamCopy.h:45
-
audio_tools::StreamCopyT::bufferSize
int bufferSize()
Provides the buffer size.
Definition: StreamCopy.h:283
-
audio_tools::StreamCopyT::setMimeCallback
void setMimeCallback(void(*callback)(const char *))
Define the callback that will notify about mime changes.
Definition: StreamCopy.h:260
-
audio_tools::StreamCopyT::setAvailableCallback
void setAvailableCallback(int(*callback)(Stream *stream))
Defines a callback that provides the available bytes at the source.
Definition: StreamCopy.h:273
-
audio_tools::StreamCopyT::getTo
Print * getTo()
Provides a pointer to the copy target. Can be used to check if the target is defined.
Definition: StreamCopy.h:84
-
audio_tools::StreamCopyT::setActive
void setActive(bool flag)
deactivate/activate copy - active by default
Definition: StreamCopy.h:314
-
audio_tools::StreamCopyT::isCheckAvailableForWrite
bool isCheckAvailableForWrite()
Is Available for Write check activated ?
Definition: StreamCopy.h:293
-
audio_tools::StreamCopyT::copy
size_t copy()
copies the data from the source to the destination and returns the processed number of bytes
Definition: StreamCopy.h:89
-
audio_tools::StreamCopyT::setCheckAvailableForWrite
void setCheckAvailableForWrite(bool flag)
Activates the check that we copy only if available for write returns a value.
Definition: StreamCopy.h:288
-
audio_tools::StreamCopyT::begin
void begin(Print &to, AudioStream &from)
assign a new output and input stream
Definition: StreamCopy.h:72
-
audio_tools::StreamCopyT::setLogName
void setLogName(const char *name)
Defines a name which will be printed in the log to identify the copier.
Definition: StreamCopy.h:324
+
audio_tools::StreamCopyT::setCheckAvailable
void setCheckAvailable(bool flag)
Activates the check that we copy only if available returns a value.
Definition: StreamCopy.h:305
+
audio_tools::StreamCopyT::copyMs
size_t copyMs(size_t millis, AudioInfo info)
Copies audio for the indicated number of milliseconds: note that the resolution is determined by the ...
Definition: StreamCopy.h:204
+
audio_tools::StreamCopyT::setMinCopySize
void setMinCopySize(int size)
Defines the minimum frame size that is used to round the copy size: 0 will automatically try to deter...
Definition: StreamCopy.h:350
+
audio_tools::StreamCopyT::minCopySize
int minCopySize()
Determine frame size.
Definition: StreamCopy.h:341
+
audio_tools::StreamCopyT::copy
size_t copy(BaseConverter &converter)
copies the data from the source to the destination and applies the converter - the result is the proc...
Definition: StreamCopy.h:102
+
audio_tools::StreamCopyT::mime
const char * mime()
Provides the actual mime type, that was determined from the first available data.
Definition: StreamCopy.h:262
+
audio_tools::StreamCopyT::copyBytes
size_t copyBytes(size_t bytes)
copies the inicated number of bytes from the source to the destination and returns the processed numb...
Definition: StreamCopy.h:108
+
audio_tools::StreamCopyT::write
size_t write(size_t len, size_t &delayCount)
blocking write - until everything is processed
Definition: StreamCopy.h:398
+
audio_tools::StreamCopyT::available
int available()
available bytes of the data source
Definition: StreamCopy.h:241
+
audio_tools::StreamCopyT::resize
void resize(int len)
resizes the copy buffer
Definition: StreamCopy.h:315
+
audio_tools::StreamCopyT::setRetry
void setRetry(int retry)
Defines the max number of retries.
Definition: StreamCopy.h:285
+
audio_tools::StreamCopyT::copyN
size_t copyN(size_t pages)
Copies pages * buffersize samples: returns the processed number of bytes.
Definition: StreamCopy.h:194
+
audio_tools::StreamCopyT::setCallbackOnWrite
void setCallbackOnWrite(void(*onWrite)(void *obj, void *buffer, size_t len), void *obj)
Defines a callback that is notified with the wirtten data.
Definition: StreamCopy.h:273
+
audio_tools::StreamCopyT::setRetryDelay
void setRetryDelay(int delay)
Defines the delay that is added before we retry an incomplete copy.
Definition: StreamCopy.h:336
+
audio_tools::StreamCopyT::setSynchAudioInfo
void setSynchAudioInfo(bool active)
Activate the synchronization from the AudioInfo form the source to the target.
Definition: StreamCopy.h:355
+
audio_tools::StreamCopyT::setDelayOnNoData
void setDelayOnNoData(int delayMs)
Defines the dealy that is used if no data is available.
Definition: StreamCopy.h:257
+
audio_tools::StreamCopyT::getFrom
Stream * getFrom()
Provides a pointer to the copy source. Can be used to check if the source is defined.
Definition: StreamCopy.h:86
+
audio_tools::StreamCopyT::copyAll
size_t copyAll(int retryCount=5, int retryWaitMs=200)
copies all data - returns the number of processed bytes
Definition: StreamCopy.h:211
+
audio_tools::StreamCopyT::notifyMime
void notifyMime(void *data, size_t len)
Update the mime type.
Definition: StreamCopy.h:434
+
audio_tools::StreamCopyT::isCheckAvailable
bool isCheckAvailable()
Is Available check activated ?
Definition: StreamCopy.h:310
+
audio_tools::StreamCopyT::isActive
bool isActive()
Check if copier is active.
Definition: StreamCopy.h:326
+
audio_tools::StreamCopyT::begin
void begin(Print &to, Stream &from)
assign a new output and input stream
Definition: StreamCopy.h:71
+
audio_tools::StreamCopyT::end
void end()
Ends the processing.
Definition: StreamCopy.h:61
+
audio_tools::StreamCopyT::begin
void begin()
(Re)starts the processing
Definition: StreamCopy.h:49
+
audio_tools::StreamCopyT::bufferSize
int bufferSize()
Provides the buffer size.
Definition: StreamCopy.h:290
+
audio_tools::StreamCopyT::setMimeCallback
void setMimeCallback(void(*callback)(const char *))
Define the callback that will notify about mime changes.
Definition: StreamCopy.h:267
+
audio_tools::StreamCopyT::setAvailableCallback
void setAvailableCallback(int(*callback)(Stream *stream))
Defines a callback that provides the available bytes at the source.
Definition: StreamCopy.h:280
+
audio_tools::StreamCopyT::getTo
Print * getTo()
Provides a pointer to the copy target. Can be used to check if the target is defined.
Definition: StreamCopy.h:91
+
audio_tools::StreamCopyT::setActive
void setActive(bool flag)
deactivate/activate copy - active by default
Definition: StreamCopy.h:321
+
audio_tools::StreamCopyT::isCheckAvailableForWrite
bool isCheckAvailableForWrite()
Is Available for Write check activated ?
Definition: StreamCopy.h:300
+
audio_tools::StreamCopyT::copy
size_t copy()
copies the data from the source to the destination and returns the processed number of bytes
Definition: StreamCopy.h:96
+
audio_tools::StreamCopyT::setCheckAvailableForWrite
void setCheckAvailableForWrite(bool flag)
Activates the check that we copy only if available for write returns a value.
Definition: StreamCopy.h:295
+
audio_tools::StreamCopyT::begin
void begin(Print &to, AudioStream &from)
assign a new output and input stream
Definition: StreamCopy.h:79
+
audio_tools::StreamCopyT::setLogName
void setLogName(const char *name)
Defines a name which will be printed in the log to identify the copier.
Definition: StreamCopy.h:331
audio_tools::Stream
Definition: NoArduino.h:125
audio_tools::Vector< uint8_t >
audio_tools
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:868
diff --git a/classaudio__tools_1_1_stream_copy_t-members.html b/classaudio__tools_1_1_stream_copy_t-members.html index ce2747722..dd3facb84 100644 --- a/classaudio__tools_1_1_stream_copy_t-members.html +++ b/classaudio__tools_1_1_stream_copy_t-members.html @@ -133,6 +133,7 @@ syncAudioInfo() (defined in StreamCopyT< T >)StreamCopyT< T >inlineprotected to (defined in StreamCopyT< T >)StreamCopyT< T >protected write(size_t len, size_t &delayCount)StreamCopyT< T >inlineprotected + ~StreamCopyT() (defined in StreamCopyT< T >)StreamCopyT< T >inline