From 9dd54934e4d2b6b6734884cdfc670d89ff6d3f5e Mon Sep 17 00:00:00 2001 From: pschatzmann Date: Tue, 5 Nov 2024 17:17:13 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20doxygen=20from=20@=20pschatzma?= =?UTF-8?q?nn/arduino-audio-tools@740b2a6cc7387a0bffdbd266d9ddf08466716a73?= =?UTF-8?q?=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _analog_driver_e_s_p32_8h_source.html | 2 +- _audio_encoded_8h_source.html | 7 +- _audio_f_f_t_8h_source.html | 2 +- _audio_faust_8h_source.html | 2 +- _audio_i_o_8h_source.html | 1209 +++++++++-------- _audio_s_t_k_8h_source.html | 2 +- _audio_streams_8h_source.html | 4 +- _audio_streams_converter_8h_source.html | 19 +- _audio_types_8h_source.html | 424 +++--- _base_converter_8h_source.html | 2 +- _codec_float_8h_source.html | 2 +- _container_ogg_8h_source.html | 2 +- _equilizer_8h_source.html | 4 +- _f_f_t_display_8h_source.html | 2 +- _frequency_detection_8h_source.html | 2 +- _i2_s_codec_stream_8h_source.html | 2 +- _i2_s_config_e_s_p32_8h_source.html | 4 +- _i2_s_config_e_s_p32_v1_8h_source.html | 4 +- _i2_s_config_std_8h_source.html | 4 +- _i2_s_e_s_p32_8h_source.html | 2 +- _i2_s_r_p2040-_m_b_e_d_8h_source.html | 2 +- _l_e_d_output_8h_source.html | 2 +- _l_e_d_output_uno_r4_8h_source.html | 2 +- _p_w_m_audio_base_8h_source.html | 2 +- _pipeline_8h_source.html | 2 +- _resample_stream_8h_source.html | 7 +- _sound_generator_8h_source.html | 2 +- _volume_control_8h_source.html | 2 +- _volume_stream_8h_source.html | 2 +- ...annel_format_converter_stream-members.html | 76 +- ...s_1_1_channel_format_converter_stream.html | 14 - ...nel_format_converter_stream_t-members.html | 76 +- ...1_1_channel_format_converter_stream_t.html | 14 - ...ools_1_1_encoded_audio_stream-members.html | 92 +- ...audio__tools_1_1_encoded_audio_stream.html | 14 - ...s_1_1_format_converter_stream-members.html | 84 +- ...io__tools_1_1_format_converter_stream.html | 14 - ...umber_format_converter_stream-members.html | 72 +- ...ls_1_1_number_format_converter_stream.html | 14 - ...ber_format_converter_stream_t-members.html | 66 +- ..._1_1_number_format_converter_stream_t.html | 14 - ...ools_1_1_reformat_base_stream-members.html | 56 +- ...audio__tools_1_1_reformat_base_stream.html | 14 - ...io__tools_1_1_resample_stream-members.html | 98 +- classaudio__tools_1_1_resample_stream.html | 14 - functions.html | 11 +- functions_func.html | 19 +- functions_func_s.html | 9 +- functions_s.html | 5 +- search/all_1.js | 299 ++-- search/all_10.js | 180 +-- search/all_11.js | 18 +- search/all_12.js | 186 +-- search/all_13.js | 631 +++++---- search/all_14.js | 124 +- search/all_15.js | 36 +- search/all_16.js | 154 +-- search/all_17.js | 70 +- search/all_18.js | 2 +- search/all_19.js | 4 +- search/all_1a.js | 52 +- search/all_2.js | 88 +- search/all_3.js | 232 ++-- search/all_4.js | 116 +- search/all_5.js | 76 +- search/all_6.js | 182 +-- search/all_7.js | 136 +- search/all_8.js | 54 +- search/all_9.js | 212 +-- search/all_a.js | 6 +- search/all_b.js | 8 +- search/all_c.js | 78 +- search/all_d.js | 166 +-- search/all_e.js | 52 +- search/all_f.js | 68 +- search/classes_0.js | 222 +-- search/classes_1.js | 46 +- search/classes_10.js | 16 +- search/classes_11.js | 84 +- search/classes_12.js | 136 +- search/classes_13.js | 56 +- search/classes_14.js | 18 +- search/classes_15.js | 122 +- search/classes_16.js | 26 +- search/classes_2.js | 92 +- search/classes_3.js | 56 +- search/classes_4.js | 30 +- search/classes_5.js | 96 +- search/classes_6.js | 52 +- search/classes_7.js | 34 +- search/classes_8.js | 62 +- search/classes_9.js | 6 +- search/classes_a.js | 2 +- search/classes_b.js | 42 +- search/classes_c.js | 72 +- search/classes_d.js | 30 +- search/classes_e.js | 32 +- search/classes_f.js | 58 +- search/enums_0.js | 6 +- search/enums_1.js | 2 +- search/enums_2.js | 2 +- search/enums_3.js | 2 +- search/enums_4.js | 2 +- search/enums_5.js | 8 +- search/enums_6.js | 8 +- search/enums_7.js | 2 +- search/enums_8.js | 2 +- search/enums_9.js | 2 +- search/files_0.js | 10 +- search/files_1.js | 18 +- search/files_2.js | 2 +- search/files_3.js | 2 +- search/functions_0.js | 2 +- search/functions_1.js | 147 +- search/functions_10.js | 4 +- search/functions_11.js | 90 +- search/functions_12.js | 487 ++++--- search/functions_13.js | 52 +- search/functions_14.js | 14 +- search/functions_15.js | 22 +- search/functions_16.js | 46 +- search/functions_17.js | 52 +- search/functions_2.js | 26 +- search/functions_3.js | 102 +- search/functions_4.js | 64 +- search/functions_5.js | 32 +- search/functions_6.js | 68 +- search/functions_7.js | 82 +- search/functions_8.js | 24 +- search/functions_9.js | 124 +- search/functions_a.js | 4 +- search/functions_b.js | 40 +- search/functions_c.js | 76 +- search/functions_d.js | 20 +- search/functions_e.js | 40 +- search/functions_f.js | 110 +- search/groups_0.js | 2 +- search/groups_1.js | 4 +- search/groups_2.js | 14 +- search/groups_3.js | 4 +- search/groups_4.js | 10 +- search/groups_5.js | 6 +- search/groups_6.js | 4 +- search/groups_7.js | 2 +- search/groups_8.js | 6 +- search/groups_9.js | 2 +- search/groups_a.js | 6 +- search/groups_b.js | 4 +- search/groups_c.js | 4 +- search/groups_d.js | 2 +- search/groups_e.js | 6 +- search/groups_f.js | 4 +- search/namespaces_0.js | 4 +- search/namespaces_1.js | 2 +- search/namespaces_2.js | 2 +- search/pages_0.js | 2 +- search/related_0.js | 2 +- search/typedefs_0.js | 2 +- search/typedefs_1.js | 2 +- search/typedefs_2.js | 2 +- search/typedefs_3.js | 2 +- search/variables_0.js | 6 +- search/variables_1.js | 12 +- search/variables_10.js | 10 +- search/variables_11.js | 6 +- search/variables_12.js | 2 +- search/variables_13.js | 4 +- search/variables_2.js | 14 +- search/variables_3.js | 14 +- search/variables_4.js | 4 +- search/variables_5.js | 18 +- search/variables_6.js | 26 +- search/variables_7.js | 2 +- search/variables_8.js | 18 +- search/variables_9.js | 2 +- search/variables_a.js | 4 +- search/variables_b.js | 8 +- search/variables_c.js | 12 +- search/variables_d.js | 20 +- search/variables_e.js | 12 +- search/variables_f.js | 8 +- 181 files changed, 4516 insertions(+), 4702 deletions(-) diff --git a/_analog_driver_e_s_p32_8h_source.html b/_analog_driver_e_s_p32_8h_source.html index c50c38186f..662cd5f8cd 100644 --- a/_analog_driver_e_s_p32_8h_source.html +++ b/_analog_driver_e_s_p32_8h_source.html @@ -417,7 +417,7 @@
AnalogDriverESP32()=default
Default constructor.
void end() override
stops the I2S and unistalls the driver
Definition: AnalogDriverESP32.h:137
virtual ~AnalogDriverESP32()
Destructor.
Definition: AnalogDriverESP32.h:41
-
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition: AudioTypes.h:325
+
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition: AudioTypes.h:301
void stop()
Public generic methods.
Definition: AudioRuntime.h:27
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:821
AnalogDriverArduino AnalogDriver
AnalogAudioStream.
Definition: AnalogDriverArduino.h:48
diff --git a/_audio_encoded_8h_source.html b/_audio_encoded_8h_source.html index a913e3fd45..4f63ca53ac 100644 --- a/_audio_encoded_8h_source.html +++ b/_audio_encoded_8h_source.html @@ -387,7 +387,7 @@
345  }
346 
347  bool begin() {
-
348  is_output_notify = false;
+
348  //is_output_notify = false;
349  reader.setByteCountFactor(10);
350  setupReader();
351  ReformatBaseStream::begin();
@@ -402,7 +402,7 @@
360  int availableForWrite() { return enc_out.availableForWrite(); }
361 
362  size_t write(const uint8_t *data, size_t len) {
-
363  addNotifyOnFirstWrite();
+
363  //addNotifyOnFirstWrite();
364  return enc_out.write(data, len);
365  }
366 
@@ -513,7 +513,7 @@
void setAudioInfo(AudioInfo from) override
Defines the sample rate, number of channels and bits per sample.
Definition: AudioCodecsBase.h:95
virtual void addNotifyAudioChange(AudioInfoSupport &bi)
Adds target to be notified about audio changes.
Definition: AudioTypes.h:160
Supports changes to the sampling rate, bits and channels.
Definition: AudioTypes.h:137
-
Base class for Output Adpapters.
Definition: AudioIO.h:223
+
Base class for Output Adpapters.
Definition: AudioIO.h:224
Abstract Audio Ouptut class.
Definition: AudioOutput.h:22
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition: BaseStream.h:109
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition: BaseStream.h:117
@@ -547,7 +547,6 @@
Abstract class: Objects can be put into a pipleline.
Definition: AudioOutput.h:97
Definition: NoArduino.h:58
Base class for chained converting streams.
Definition: AudioIO.h:142
-
void addNotifyOnFirstWrite()
Add notification on first call of write.
Definition: AudioIO.h:204
virtual void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition: AudioIO.h:144
Definition: NoArduino.h:125
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:821
diff --git a/_audio_f_f_t_8h_source.html b/_audio_f_f_t_8h_source.html index 44d0ae73e8..44d483c254 100644 --- a/_audio_f_f_t_8h_source.html +++ b/_audio_f_f_t_8h_source.html @@ -539,7 +539,7 @@
virtual bool getBin(int pos, FFTBin &bin)
gets the value of a bin
Definition: AudioFFT.h:116
virtual float getValue(int pos)=0
Get result value from Reverse FFT.
const char * note(float frequency, float &diff) const
Determines the closes note for a frequency. We also return the frequency difference.
Definition: MusicalNotes.h:169
-
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition: AudioTypes.h:325
+
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition: AudioTypes.h:301
Definition: NoArduino.h:58
virtual T read()
reads a single value
Definition: Buffers.h:309
diff --git a/_audio_faust_8h_source.html b/_audio_faust_8h_source.html index 9e57a1d547..4f4870b1c6 100644 --- a/_audio_faust_8h_source.html +++ b/_audio_faust_8h_source.html @@ -457,7 +457,7 @@
void allocateFloatBuffer(int samples, bool allocate_out)
Allocate the buffer that is needed by faust.
Definition: AudioFaust.h:332
bool begin(AudioInfo cfg)
Checks the parameters and starts the processing.
Definition: AudioFaust.h:54
virtual bool setLabelValue(const char *label, FAUSTFLOAT value)
Defines the value of a parameter.
Definition: AudioFaust.h:177
-
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition: AudioTypes.h:325
+
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition: AudioTypes.h:301
Definition: NoArduino.h:58
Memory manager which uses psram when it is available.
Definition: AudioFaustDSP.h:181
minimal dsp base class needed by Faust
Definition: AudioFaustDSP.h:25
diff --git a/_audio_i_o_8h_source.html b/_audio_i_o_8h_source.html index 319e83ea18..770795f531 100644 --- a/_audio_i_o_8h_source.html +++ b/_audio_i_o_8h_source.html @@ -200,626 +200,627 @@
151  TRACED();
152  p_stream = &stream;
153  p_print = &stream;
-
154  setNotifyOnOutput(stream);
-
155  }
-
156 
-
157  virtual void setOutput(AudioOutput &print) {
-
158  TRACED();
-
159  p_print = &print;
-
160  setNotifyOnOutput(print);
-
161  }
-
162 
-
163  virtual void setOutput(Print &print) override {
-
164  TRACED();
-
165  p_print = &print;
-
166  }
-
167 
-
168  virtual Print *getPrint() { return p_print; }
-
169 
-
170  virtual Stream *getStream() { return p_stream; }
-
171 
-
172  size_t readBytes(uint8_t *data, size_t len) override {
-
173  LOGD("ReformatBaseStream::readBytes: %d", (int)len);
-
174  return reader.readBytes(data, len);
-
175  }
-
176 
-
177  int available() override {
-
178  return DEFAULT_BUFFER_SIZE; // reader.availableForWrite();
-
179  }
-
180 
-
181  int availableForWrite() override {
-
182  return DEFAULT_BUFFER_SIZE; // reader.availableForWrite();
-
183  }
-
184 
-
185  virtual float getByteFactor() = 0;
-
186 
-
187  void end() override {
-
188  TRACED();
-
189  AudioStream::end();
-
190  reader.end();
-
191  }
-
192 
-
193  protected:
-
194  TransformationReader<ReformatBaseStream> reader;
-
195  Stream *p_stream = nullptr;
-
196  Print *p_print = nullptr;
-
197  bool is_output_notify = false;
-
198  AudioInfoSupport *p_notify_on_output = nullptr;
-
199 
-
201  void setNotifyOnOutput(AudioInfoSupport &info) { p_notify_on_output = &info; }
-
202 
-
204  void addNotifyOnFirstWrite() {
-
205  if (!is_output_notify) {
-
206  if (p_notify_on_output != nullptr)
-
207  addNotifyAudioChange(*p_notify_on_output);
-
208  is_output_notify = true;
-
209  }
-
210  }
-
211 
-
212  void setupReader() {
-
213  if (getStream() != nullptr) {
-
214  reader.begin(this, getStream());
-
215  }
-
216  }
-
217 };
-
218 
-
223 class AudioOutputAdapter : public AudioOutput {};
-
224 
-
229 class AdapterPrintToAudioOutput : public AudioOutputAdapter {
-
230  public:
-
231  AdapterPrintToAudioOutput(Print &print) { p_print = &print; }
-
232  void setAudioInfo(AudioInfo info) {}
-
233  size_t write(const uint8_t *data, size_t len) {
-
234  return p_print->write(data, len);
-
235  }
-
237  virtual bool isDeletable() { return true; }
-
238 
-
239  protected:
-
240  Print *p_print = nullptr;
-
241 };
-
242 
-
247 class AdapterAudioStreamToAudioOutput : public AudioOutputAdapter {
-
248  public:
-
249  AdapterAudioStreamToAudioOutput() = default;
-
250 
-
251  AdapterAudioStreamToAudioOutput(AudioStream &stream) { setStream(stream); }
-
252 
-
253  void setStream(AudioStream &stream) { p_stream = &stream; }
-
254 
-
255  void setAudioInfo(AudioInfo info) override { p_stream->setAudioInfo(info); }
-
256 
-
257  AudioInfo audioInfo() override { return p_stream->audioInfo(); }
-
258 
-
259  size_t write(const uint8_t *data, size_t len) override {
-
260  return p_stream->write(data, len);
-
261  }
-
262 
-
263  int availableForWrite() override { return p_stream->availableForWrite(); }
-
264 
-
265  bool begin() override { return p_stream->begin(); }
-
266 
-
267  void end() override { p_stream->end(); }
-
268 
-
270  virtual bool isDeletable() { return true; }
-
271 
-
272  operator bool() override { return *p_stream; }
-
273 
-
274  protected:
-
275  AudioStream *p_stream = nullptr;
-
276 };
-
277 
-
282 class AdapterAudioOutputToAudioStream : public AudioStream {
-
283  public:
-
284  AdapterAudioOutputToAudioStream() = default;
-
285 
-
286  AdapterAudioOutputToAudioStream(AudioOutput &stream) { setOutput(stream); }
-
287 
-
288  void setOutput(AudioOutput &stream) { p_stream = &stream; }
-
289 
-
290  void setAudioInfo(AudioInfo info) override { p_stream->setAudioInfo(info); }
-
291 
-
292  AudioInfo audioInfo() override { return p_stream->audioInfo(); }
-
293 
-
294  size_t write(const uint8_t *data, size_t len) override {
-
295  return p_stream->write(data, len);
-
296  }
-
297 
-
298  bool begin() override { return p_stream->begin(); }
-
299 
-
300  void end() override { p_stream->end(); }
-
301 
-
303  virtual bool isDeletable() { return true; }
-
304 
-
305  operator bool() override { return *p_stream; }
-
306 
-
307  protected:
-
308  AudioOutput *p_stream = nullptr;
-
309 };
-
310 
-
317 class MultiOutput : public ModifyingOutput {
-
318  public:
-
320  MultiOutput() = default;
-
321 
-
322  MultiOutput(Print &out) { add(out); }
-
323 
-
325  MultiOutput(AudioOutput &out) { add(out); }
-
326 
-
327  MultiOutput(AudioStream &out) { add(out); }
-
328 
-
330  MultiOutput(AudioOutput &out1, AudioOutput &out2) {
-
331  add(out1);
-
332  add(out2);
-
333  }
-
334 
-
336  MultiOutput(AudioStream &out1, AudioStream &out2) {
-
337  add(out1);
-
338  add(out2);
-
339  }
-
340 
-
343  MultiOutput(Print &out1, Print &out2) {
-
344  add(out1);
-
345  add(out2);
-
346  }
-
347 
-
348  virtual ~MultiOutput() {
-
349  for (int j = 0; j < vector.size(); j++) {
-
350  if (vector[j]->isDeletable()) {
-
351  delete vector[j];
-
352  }
-
353  }
-
354  }
-
355 
-
357  void add(AudioOutput &out) { vector.push_back(&out); }
-
358 
-
360  void add(AudioStream &stream) {
-
361  AdapterAudioStreamToAudioOutput *out =
-
362  new AdapterAudioStreamToAudioOutput(stream);
-
363  vector.push_back(out);
-
364  }
-
365 
-
366  void add(Print &print) {
-
367  AdapterPrintToAudioOutput *out = new AdapterPrintToAudioOutput(print);
-
368  vector.push_back(out);
-
369  }
-
370 
-
371  void flush() {
-
372  for (int j = 0; j < vector.size(); j++) {
-
373  vector[j]->flush();
-
374  }
-
375  }
-
376 
-
377  void setAudioInfo(AudioInfo info) {
-
378  for (int j = 0; j < vector.size(); j++) {
-
379  vector[j]->setAudioInfo(info);
-
380  }
-
381  }
-
382 
-
383  size_t write(const uint8_t *data, size_t len) {
-
384  for (int j = 0; j < vector.size(); j++) {
-
385  int open = len;
-
386  int start = 0;
-
387  while (open > 0) {
-
388  int written = vector[j]->write(data + start, open);
-
389  open -= written;
-
390  start += written;
-
391  }
-
392  }
-
393  return len;
-
394  }
-
395 
-
396  size_t write(uint8_t ch) {
-
397  for (int j = 0; j < vector.size(); j++) {
-
398  int open = 1;
-
399  while (open > 0) {
-
400  open -= vector[j]->write(ch);
-
401  }
-
402  }
-
403  return 1;
-
404  }
-
405 
-
406  protected:
-
407  Vector<AudioOutput *> vector;
-
409  void setOutput(Print &out) { add(out); }
-
410 };
-
411 
-
421 class TimedStream : public ModifyingStream {
-
422  public:
-
423  TimedStream() = default;
-
424 
-
425  TimedStream(AudioStream &io, long startSeconds = 0, long endSeconds = -1) {
-
426  p_stream = &io;
-
427  p_print = &io;
-
428  p_info = &io;
-
429  setStartSec(startSeconds);
-
430  setEndSec(endSeconds);
-
431  }
-
432 
-
433  TimedStream(AudioOutput &o, long startSeconds = 0, long endSeconds = -1) {
-
434  p_print = &o;
-
435  p_info = &o;
-
436  setStartSec(startSeconds);
-
437  setEndSec(endSeconds);
-
438  }
-
439 
-
442  void setStartSec(uint32_t startSeconds) {
-
443  start_ms = startSeconds * 1000;
-
444  calculateByteLimits();
-
445  }
-
446 
-
448  void setStartMs(uint32_t ms) {
-
449  start_ms = ms;
-
450  calculateByteLimits();
-
451  }
-
452 
-
455  void setEndSec(uint32_t endSeconds) {
-
456  end_ms = endSeconds * 1000;
-
457  calculateByteLimits();
-
458  }
-
459 
-
461  void setEndMs(uint32_t ms) {
-
462  end_ms = ms;
-
463  calculateByteLimits();
-
464  }
-
465 
-
467  bool isPlaying() {
-
468  if (current_bytes < start_bytes) return false;
-
469  if (end_bytes > 0 && current_bytes > end_bytes) return false;
-
470  return true;
-
471  }
-
472 
-
474  bool isActive() {
-
475  return (current_bytes < end_bytes && current_bytes >= start_bytes);
-
476  }
-
477 
-
478  bool begin(AudioInfo info) {
-
479  setAudioInfo(info);
-
480  return begin();
-
481  }
-
482 
-
483  bool begin() override {
-
484  calculateByteLimits();
-
485  current_bytes = 0;
-
486  LOGI("byte range %u - %u",(unsigned) start_bytes,(unsigned) end_bytes);
-
487  return true;
-
488  }
-
489 
-
490  operator bool() { return isActive(); }
-
491 
-
495  size_t readBytes(uint8_t *data, size_t len) override {
-
496  // if reading is not supported we stop
-
497  if (p_stream == nullptr) return 0;
-
498  // Positioin to start
-
499  if (start_bytes > current_bytes){
-
500  consumeBytes(start_bytes - current_bytes);
-
501  }
-
502  // if we are past the end we stop
-
503  if (!isActive()) return 0;
-
504  // read the data now
-
505  size_t result = 0;
-
506  do {
-
507  result = p_stream->readBytes(data, len);
-
508  current_bytes += len;
-
509  // ignore data before start time
-
510  } while (result > 0 && current_bytes < start_bytes);
-
511  return isPlaying() ? result : 0;
-
512  }
-
513 
-
515  size_t write(const uint8_t *data, size_t len) override {
-
516  if (current_bytes >= end_bytes) return 0;
-
517  current_bytes += len;
-
518  if (current_bytes < start_bytes) return len;
-
519  return p_print->write(data, len);
-
520  }
-
521 
-
523  int available() override {
-
524  if (p_stream == nullptr) return 0;
-
525  return current_bytes < end_bytes ? p_stream->available() : 0;
-
526  }
-
527 
-
529  void setAudioInfo(AudioInfo info) override {
-
530  AudioStream::setAudioInfo(info);
-
531  if (p_info) p_info->setAudioInfo(info);
-
532  calculateByteLimits();
-
533  }
-
534 
-
535  int availableForWrite() override {
-
536  return current_bytes < end_bytes ? p_print->availableForWrite() : 0;
-
537  }
-
538 
-
541  void setCompressionRatio(float ratio) { compression_ratio = ratio; }
-
542 
-
544  int bytesPerSecond() {
-
545  return info.sample_rate * info.channels * info.bits_per_sample / 8;
-
546  }
-
547 
-
548  void setOutput(Print &out) { p_print = &out; }
-
549 
-
550  void setStream(Stream &stream) {
-
551  p_print = &stream;
-
552  p_stream = &stream;
-
553  }
-
554 
-
555  void setOutput(AudioOutput &out) {
-
556  p_print = &out;
-
557  p_info = &out;
-
558  }
-
559 
-
560  void setStream(AudioOutput &out) {
-
561  p_print = &out;
-
562  p_info = &out;
-
563  }
-
564 
-
565  void setStream(AudioStream &stream) {
-
566  p_print = &stream;
-
567  p_stream = &stream;
-
568  p_info = &stream;
-
569  }
-
570 
-
571  size_t size() {
-
572  return end_bytes - start_bytes;
-
573  }
-
574 
-
575  protected:
-
576  Stream *p_stream = nullptr;
-
577  Print *p_print = nullptr;
-
578  AudioInfoSupport *p_info = nullptr;
-
579  uint32_t start_ms = 0;
-
580  uint32_t end_ms = UINT32_MAX;
-
581  uint32_t start_bytes = 0;
-
582  uint32_t end_bytes = UINT32_MAX;
-
583  uint32_t current_bytes = 0;
-
584  float compression_ratio = 1.0;
-
585 
-
586  void consumeBytes(uint32_t len){
-
587  int open = len;
-
588  uint8_t buffer[1024];
-
589  while (open > 0){
-
590  int toread = min(1024, open);
-
591  p_stream->readBytes(buffer, toread);
-
592  open -= toread;
-
593  }
-
594  current_bytes += len;
-
595  LOGD("consumed %u -> %u",(unsigned) len, (unsigned)current_bytes);
-
596  }
-
597 
-
598  void calculateByteLimits() {
-
599  float bytes_per_second = bytesPerSecond();
-
600  if (bytes_per_second > 0) {
-
601  start_bytes = bytes_per_second * start_ms / compression_ratio / 1000;
-
602  end_bytes = bytes_per_second * end_ms / compression_ratio / 1000;
-
603  } else {
-
604  LOGE("AudioInfo not defined");
-
605  }
-
606  }
-
607 };
-
608 
-
618 class ChannelsSelectOutput : public AudioOutput {
-
619  public:
-
620  ChannelsSelectOutput() = default;
-
621 
-
622  bool begin(AudioInfo info) {
-
623  setAudioInfo(info);
-
624  return begin();
-
625  }
-
626 
-
627  bool begin() {
-
628  AudioOutput::begin();
-
629  // make sure that selected channels are valid
-
630  for (auto &out : out_channels) {
-
631  for (auto &ch : out.channels) {
-
632  if (ch > cfg.channels - 1) {
-
633  LOGE("Channel '%d' not valid for max %d channels", ch, cfg.channels);
-
634  return false;
-
635  }
-
636  }
-
637  }
-
638  return true;
-
639  }
-
640 
-
643  void addOutput(AudioOutput &out, uint16_t channel) {
-
644  Vector<uint16_t> channels;
-
645  channels.push_back(channel);
-
646  ChannelSelectionOutputDef def;
-
647  def.channels = channels;
-
648  def.p_out = &out;
-
649  def.p_audio_info = &out;
-
650  out_channels.push_back(def);
-
651  }
-
652 
-
655  void addOutput(AudioStream &out, uint16_t channel) {
-
656  Vector<uint16_t> channels;
-
657  channels.push_back(channel);
-
658  ChannelSelectionOutputDef def;
-
659  def.channels = channels;
-
660  def.p_out = &out;
-
661  def.p_audio_info = &out;
-
662  out_channels.push_back(def);
-
663  }
-
664 
-
667  void addOutput(Print &out, uint16_t channel) {
-
668  Vector<uint16_t> channels;
-
669  channels.push_back(channel);
-
670  ChannelSelectionOutputDef def;
-
671  def.channels = channels;
-
672  def.p_out = &out;
-
673  out_channels.push_back(def);
-
674  }
-
675 
-
678  void addOutput(Print &out, uint16_t left, uint16_t right) {
-
679  Vector<uint16_t> channels;
-
680  channels.push_back(left);
-
681  channels.push_back(right);
-
682  ChannelSelectionOutputDef def;
-
683  def.channels = channels;
-
684  def.p_out = &out;
-
685  out_channels.push_back(def);
-
686  }
-
687 
-
690  void addOutput(AudioOutput &out, uint16_t left, uint16_t right) {
-
691  Vector<uint16_t> channels;
-
692  channels.push_back(left);
-
693  channels.push_back(right);
-
694  ChannelSelectionOutputDef def;
-
695  def.channels = channels;
-
696  def.p_out = &out;
-
697  def.p_audio_info = &out;
-
698  out_channels.push_back(def);
-
699  }
-
700 
-
703  void addOutput(AudioStream &out, uint16_t left, uint16_t right) {
-
704  Vector<uint16_t> channels;
-
705  channels.push_back(left);
-
706  channels.push_back(right);
-
707  ChannelSelectionOutputDef def;
-
708  def.channels = channels;
-
709  def.p_out = &out;
-
710  def.p_audio_info = &out;
-
711  out_channels.push_back(def);
-
712  }
-
713 
-
714  size_t write(const uint8_t *data, size_t len) override {
-
715  if (!is_active) return false;
-
716  LOGD("write %d", (int)len);
-
717  switch (cfg.bits_per_sample) {
-
718  case 16:
-
719  return writeT<int16_t>(data, len);
-
720  case 24:
-
721  return writeT<int24_t>(data, len);
-
722  case 32:
-
723  return writeT<int32_t>(data, len);
-
724  default:
-
725  return 0;
-
726  }
-
727  }
-
728 
-
729  void setAudioInfo(AudioInfo ai) override {
-
730  this->cfg = ai;
-
731  //notifyAudioChange(ai);
-
732  for (auto &info : out_channels) {
-
733  auto p_notify = info.p_audio_info;
-
734  if (p_notify != nullptr) {
-
735  AudioInfo result{ai};
-
736  result.channels = info.channels.size();
-
737  p_notify->setAudioInfo(result);
-
738  }
-
739  }
-
740  }
-
741 
-
742  protected:
-
743  struct ChannelSelectionOutputDef {
-
744  Print *p_out = nullptr;
-
745  AudioInfoSupport *p_audio_info = nullptr;
-
746  SingleBuffer<uint8_t> buffer{CHANNEL_SELECT_BUFFER_SIZE};
-
747  Vector<uint16_t> channels{0};
-
748  };
-
749  Vector<ChannelSelectionOutputDef> out_channels{0};
-
750 
-
751  template <typename T>
-
752  size_t writeT(const uint8_t *buffer, size_t size) {
-
753  if (!is_active) return 0;
-
754  int sample_count = size / sizeof(T);
-
755  //int result_size = sample_count / cfg.channels;
-
756  T *data = (T *)buffer;
-
757 
-
758  for (int i = 0; i < sample_count; i += cfg.channels) {
-
759  T *frame = data + i;
-
760  for (auto &out : out_channels) {
-
761  T out_frame[out.channels.size()] = {0};
-
762  int ch_out = 0;
-
763  for (auto &ch : out.channels) {
-
764  // make sure we have a valid channel
-
765  int channel = (ch < cfg.channels) ? ch : cfg.channels - 1;
-
766  out_frame[ch_out++] = frame[channel];
-
767  }
-
768  // write to buffer
-
769  size_t written = out.buffer.writeArray((const uint8_t *)&out_frame, sizeof(out_frame));
-
770  // write buffer to final output
-
771  if (out.buffer.availableForWrite()<sizeof(out_frame)){
-
772  out.p_out->write(out.buffer.data(), out.buffer.available());
-
773  out.buffer.reset();
-
774  }
-
775  // if (written != sizeof(out_frame)) {
-
776  // LOGW("Could not write all samples %d -> %d", sizeof(out_frame), written);
-
777  // }
-
778  }
-
779  }
-
780  return size;
-
781  }
-
782 
-
784  int getChannels(Print *out, int defaultChannels) {
-
785  for (auto &channels_select : out_channels) {
-
786  if (channels_select.p_out == out) return channels_select.channels.size();
-
787  }
-
788  return defaultChannels;
-
789  }
-
790 };
-
791 
-
792 } // namespace audio_tools
-
Wrapper which converts a AudioStream to a AudioOutput.
Definition: AudioIO.h:282
-
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition: AudioIO.h:303
-
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition: AudioIO.h:290
-
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition: AudioIO.h:292
-
Wrapper which converts a AudioStream to a AudioOutput.
Definition: AudioIO.h:247
-
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition: AudioIO.h:270
-
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition: AudioIO.h:255
-
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition: AudioIO.h:257
-
Wrapper which converts a Print to a AudioOutput.
Definition: AudioIO.h:229
-
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition: AudioIO.h:237
-
void setAudioInfo(AudioInfo info)
Defines the input AudioInfo.
Definition: AudioIO.h:232
+
154  //setNotifyOnOutput(stream);
+
155  addNotifyAudioChange(stream);
+
156  }
+
157 
+
158  virtual void setOutput(AudioOutput &print) {
+
159  TRACED();
+
160  p_print = &print;
+
161  addNotifyAudioChange(print);
+
162  }
+
163 
+
164  virtual void setOutput(Print &print) override {
+
165  TRACED();
+
166  p_print = &print;
+
167  }
+
168 
+
169  virtual Print *getPrint() { return p_print; }
+
170 
+
171  virtual Stream *getStream() { return p_stream; }
+
172 
+
173  size_t readBytes(uint8_t *data, size_t len) override {
+
174  LOGD("ReformatBaseStream::readBytes: %d", (int)len);
+
175  return reader.readBytes(data, len);
+
176  }
+
177 
+
178  int available() override {
+
179  return DEFAULT_BUFFER_SIZE; // reader.availableForWrite();
+
180  }
+
181 
+
182  int availableForWrite() override {
+
183  return DEFAULT_BUFFER_SIZE; // reader.availableForWrite();
+
184  }
+
185 
+
186  virtual float getByteFactor() = 0;
+
187 
+
188  void end() override {
+
189  TRACED();
+
190  AudioStream::end();
+
191  reader.end();
+
192  }
+
193 
+
194  protected:
+
195  TransformationReader<ReformatBaseStream> reader;
+
196  Stream *p_stream = nullptr;
+
197  Print *p_print = nullptr;
+
198 // bool is_output_notify = false;
+
199 // AudioInfoSupport *p_notify_on_output = nullptr;
+
200 
+
201  // /// Define potential notification
+
202  // void setNotifyOnOutput(AudioInfoSupport &info) { p_notify_on_output = &info; }
+
203 
+
204  // /// Add notification on first call of write
+
205  // void addNotifyOnFirstWrite() {
+
206  // if (!is_output_notify) {
+
207  // if (p_notify_on_output != nullptr)
+
208  // addNotifyAudioChange(*p_notify_on_output);
+
209  // is_output_notify = true;
+
210  // }
+
211  // }
+
212 
+
213  void setupReader() {
+
214  if (getStream() != nullptr) {
+
215  reader.begin(this, getStream());
+
216  }
+
217  }
+
218 };
+
219 
+
224 class AudioOutputAdapter : public AudioOutput {};
+
225 
+
230 class AdapterPrintToAudioOutput : public AudioOutputAdapter {
+
231  public:
+
232  AdapterPrintToAudioOutput(Print &print) { p_print = &print; }
+
233  void setAudioInfo(AudioInfo info) {}
+
234  size_t write(const uint8_t *data, size_t len) {
+
235  return p_print->write(data, len);
+
236  }
+
238  virtual bool isDeletable() { return true; }
+
239 
+
240  protected:
+
241  Print *p_print = nullptr;
+
242 };
+
243 
+
248 class AdapterAudioStreamToAudioOutput : public AudioOutputAdapter {
+
249  public:
+
250  AdapterAudioStreamToAudioOutput() = default;
+
251 
+
252  AdapterAudioStreamToAudioOutput(AudioStream &stream) { setStream(stream); }
+
253 
+
254  void setStream(AudioStream &stream) { p_stream = &stream; }
+
255 
+
256  void setAudioInfo(AudioInfo info) override { p_stream->setAudioInfo(info); }
+
257 
+
258  AudioInfo audioInfo() override { return p_stream->audioInfo(); }
+
259 
+
260  size_t write(const uint8_t *data, size_t len) override {
+
261  return p_stream->write(data, len);
+
262  }
+
263 
+
264  int availableForWrite() override { return p_stream->availableForWrite(); }
+
265 
+
266  bool begin() override { return p_stream->begin(); }
+
267 
+
268  void end() override { p_stream->end(); }
+
269 
+
271  virtual bool isDeletable() { return true; }
+
272 
+
273  operator bool() override { return *p_stream; }
+
274 
+
275  protected:
+
276  AudioStream *p_stream = nullptr;
+
277 };
+
278 
+
283 class AdapterAudioOutputToAudioStream : public AudioStream {
+
284  public:
+
285  AdapterAudioOutputToAudioStream() = default;
+
286 
+
287  AdapterAudioOutputToAudioStream(AudioOutput &stream) { setOutput(stream); }
+
288 
+
289  void setOutput(AudioOutput &stream) { p_stream = &stream; }
+
290 
+
291  void setAudioInfo(AudioInfo info) override { p_stream->setAudioInfo(info); }
+
292 
+
293  AudioInfo audioInfo() override { return p_stream->audioInfo(); }
+
294 
+
295  size_t write(const uint8_t *data, size_t len) override {
+
296  return p_stream->write(data, len);
+
297  }
+
298 
+
299  bool begin() override { return p_stream->begin(); }
+
300 
+
301  void end() override { p_stream->end(); }
+
302 
+
304  virtual bool isDeletable() { return true; }
+
305 
+
306  operator bool() override { return *p_stream; }
+
307 
+
308  protected:
+
309  AudioOutput *p_stream = nullptr;
+
310 };
+
311 
+
318 class MultiOutput : public ModifyingOutput {
+
319  public:
+
321  MultiOutput() = default;
+
322 
+
323  MultiOutput(Print &out) { add(out); }
+
324 
+
326  MultiOutput(AudioOutput &out) { add(out); }
+
327 
+
328  MultiOutput(AudioStream &out) { add(out); }
+
329 
+
331  MultiOutput(AudioOutput &out1, AudioOutput &out2) {
+
332  add(out1);
+
333  add(out2);
+
334  }
+
335 
+
337  MultiOutput(AudioStream &out1, AudioStream &out2) {
+
338  add(out1);
+
339  add(out2);
+
340  }
+
341 
+
344  MultiOutput(Print &out1, Print &out2) {
+
345  add(out1);
+
346  add(out2);
+
347  }
+
348 
+
349  virtual ~MultiOutput() {
+
350  for (int j = 0; j < vector.size(); j++) {
+
351  if (vector[j]->isDeletable()) {
+
352  delete vector[j];
+
353  }
+
354  }
+
355  }
+
356 
+
358  void add(AudioOutput &out) { vector.push_back(&out); }
+
359 
+
361  void add(AudioStream &stream) {
+
362  AdapterAudioStreamToAudioOutput *out =
+
363  new AdapterAudioStreamToAudioOutput(stream);
+
364  vector.push_back(out);
+
365  }
+
366 
+
367  void add(Print &print) {
+
368  AdapterPrintToAudioOutput *out = new AdapterPrintToAudioOutput(print);
+
369  vector.push_back(out);
+
370  }
+
371 
+
372  void flush() {
+
373  for (int j = 0; j < vector.size(); j++) {
+
374  vector[j]->flush();
+
375  }
+
376  }
+
377 
+
378  void setAudioInfo(AudioInfo info) {
+
379  for (int j = 0; j < vector.size(); j++) {
+
380  vector[j]->setAudioInfo(info);
+
381  }
+
382  }
+
383 
+
384  size_t write(const uint8_t *data, size_t len) {
+
385  for (int j = 0; j < vector.size(); j++) {
+
386  int open = len;
+
387  int start = 0;
+
388  while (open > 0) {
+
389  int written = vector[j]->write(data + start, open);
+
390  open -= written;
+
391  start += written;
+
392  }
+
393  }
+
394  return len;
+
395  }
+
396 
+
397  size_t write(uint8_t ch) {
+
398  for (int j = 0; j < vector.size(); j++) {
+
399  int open = 1;
+
400  while (open > 0) {
+
401  open -= vector[j]->write(ch);
+
402  }
+
403  }
+
404  return 1;
+
405  }
+
406 
+
407  protected:
+
408  Vector<AudioOutput *> vector;
+
410  void setOutput(Print &out) { add(out); }
+
411 };
+
412 
+
422 class TimedStream : public ModifyingStream {
+
423  public:
+
424  TimedStream() = default;
+
425 
+
426  TimedStream(AudioStream &io, long startSeconds = 0, long endSeconds = -1) {
+
427  p_stream = &io;
+
428  p_print = &io;
+
429  p_info = &io;
+
430  setStartSec(startSeconds);
+
431  setEndSec(endSeconds);
+
432  }
+
433 
+
434  TimedStream(AudioOutput &o, long startSeconds = 0, long endSeconds = -1) {
+
435  p_print = &o;
+
436  p_info = &o;
+
437  setStartSec(startSeconds);
+
438  setEndSec(endSeconds);
+
439  }
+
440 
+
443  void setStartSec(uint32_t startSeconds) {
+
444  start_ms = startSeconds * 1000;
+
445  calculateByteLimits();
+
446  }
+
447 
+
449  void setStartMs(uint32_t ms) {
+
450  start_ms = ms;
+
451  calculateByteLimits();
+
452  }
+
453 
+
456  void setEndSec(uint32_t endSeconds) {
+
457  end_ms = endSeconds * 1000;
+
458  calculateByteLimits();
+
459  }
+
460 
+
462  void setEndMs(uint32_t ms) {
+
463  end_ms = ms;
+
464  calculateByteLimits();
+
465  }
+
466 
+
468  bool isPlaying() {
+
469  if (current_bytes < start_bytes) return false;
+
470  if (end_bytes > 0 && current_bytes > end_bytes) return false;
+
471  return true;
+
472  }
+
473 
+
475  bool isActive() {
+
476  return (current_bytes < end_bytes && current_bytes >= start_bytes);
+
477  }
+
478 
+
479  bool begin(AudioInfo info) {
+
480  setAudioInfo(info);
+
481  return begin();
+
482  }
+
483 
+
484  bool begin() override {
+
485  calculateByteLimits();
+
486  current_bytes = 0;
+
487  LOGI("byte range %u - %u",(unsigned) start_bytes,(unsigned) end_bytes);
+
488  return true;
+
489  }
+
490 
+
491  operator bool() { return isActive(); }
+
492 
+
496  size_t readBytes(uint8_t *data, size_t len) override {
+
497  // if reading is not supported we stop
+
498  if (p_stream == nullptr) return 0;
+
499  // Positioin to start
+
500  if (start_bytes > current_bytes){
+
501  consumeBytes(start_bytes - current_bytes);
+
502  }
+
503  // if we are past the end we stop
+
504  if (!isActive()) return 0;
+
505  // read the data now
+
506  size_t result = 0;
+
507  do {
+
508  result = p_stream->readBytes(data, len);
+
509  current_bytes += len;
+
510  // ignore data before start time
+
511  } while (result > 0 && current_bytes < start_bytes);
+
512  return isPlaying() ? result : 0;
+
513  }
+
514 
+
516  size_t write(const uint8_t *data, size_t len) override {
+
517  if (current_bytes >= end_bytes) return 0;
+
518  current_bytes += len;
+
519  if (current_bytes < start_bytes) return len;
+
520  return p_print->write(data, len);
+
521  }
+
522 
+
524  int available() override {
+
525  if (p_stream == nullptr) return 0;
+
526  return current_bytes < end_bytes ? p_stream->available() : 0;
+
527  }
+
528 
+
530  void setAudioInfo(AudioInfo info) override {
+
531  AudioStream::setAudioInfo(info);
+
532  if (p_info) p_info->setAudioInfo(info);
+
533  calculateByteLimits();
+
534  }
+
535 
+
536  int availableForWrite() override {
+
537  return current_bytes < end_bytes ? p_print->availableForWrite() : 0;
+
538  }
+
539 
+
542  void setCompressionRatio(float ratio) { compression_ratio = ratio; }
+
543 
+
545  int bytesPerSecond() {
+
546  return info.sample_rate * info.channels * info.bits_per_sample / 8;
+
547  }
+
548 
+
549  void setOutput(Print &out) { p_print = &out; }
+
550 
+
551  void setStream(Stream &stream) {
+
552  p_print = &stream;
+
553  p_stream = &stream;
+
554  }
+
555 
+
556  void setOutput(AudioOutput &out) {
+
557  p_print = &out;
+
558  p_info = &out;
+
559  }
+
560 
+
561  void setStream(AudioOutput &out) {
+
562  p_print = &out;
+
563  p_info = &out;
+
564  }
+
565 
+
566  void setStream(AudioStream &stream) {
+
567  p_print = &stream;
+
568  p_stream = &stream;
+
569  p_info = &stream;
+
570  }
+
571 
+
572  size_t size() {
+
573  return end_bytes - start_bytes;
+
574  }
+
575 
+
576  protected:
+
577  Stream *p_stream = nullptr;
+
578  Print *p_print = nullptr;
+
579  AudioInfoSupport *p_info = nullptr;
+
580  uint32_t start_ms = 0;
+
581  uint32_t end_ms = UINT32_MAX;
+
582  uint32_t start_bytes = 0;
+
583  uint32_t end_bytes = UINT32_MAX;
+
584  uint32_t current_bytes = 0;
+
585  float compression_ratio = 1.0;
+
586 
+
587  void consumeBytes(uint32_t len){
+
588  int open = len;
+
589  uint8_t buffer[1024];
+
590  while (open > 0){
+
591  int toread = min(1024, open);
+
592  p_stream->readBytes(buffer, toread);
+
593  open -= toread;
+
594  }
+
595  current_bytes += len;
+
596  LOGD("consumed %u -> %u",(unsigned) len, (unsigned)current_bytes);
+
597  }
+
598 
+
599  void calculateByteLimits() {
+
600  float bytes_per_second = bytesPerSecond();
+
601  if (bytes_per_second > 0) {
+
602  start_bytes = bytes_per_second * start_ms / compression_ratio / 1000;
+
603  end_bytes = bytes_per_second * end_ms / compression_ratio / 1000;
+
604  } else {
+
605  LOGE("AudioInfo not defined");
+
606  }
+
607  }
+
608 };
+
609 
+
619 class ChannelsSelectOutput : public AudioOutput {
+
620  public:
+
621  ChannelsSelectOutput() = default;
+
622 
+
623  bool begin(AudioInfo info) {
+
624  setAudioInfo(info);
+
625  return begin();
+
626  }
+
627 
+
628  bool begin() {
+
629  AudioOutput::begin();
+
630  // make sure that selected channels are valid
+
631  for (auto &out : out_channels) {
+
632  for (auto &ch : out.channels) {
+
633  if (ch > cfg.channels - 1) {
+
634  LOGE("Channel '%d' not valid for max %d channels", ch, cfg.channels);
+
635  return false;
+
636  }
+
637  }
+
638  }
+
639  return true;
+
640  }
+
641 
+
644  void addOutput(AudioOutput &out, uint16_t channel) {
+
645  Vector<uint16_t> channels;
+
646  channels.push_back(channel);
+
647  ChannelSelectionOutputDef def;
+
648  def.channels = channels;
+
649  def.p_out = &out;
+
650  def.p_audio_info = &out;
+
651  out_channels.push_back(def);
+
652  }
+
653 
+
656  void addOutput(AudioStream &out, uint16_t channel) {
+
657  Vector<uint16_t> channels;
+
658  channels.push_back(channel);
+
659  ChannelSelectionOutputDef def;
+
660  def.channels = channels;
+
661  def.p_out = &out;
+
662  def.p_audio_info = &out;
+
663  out_channels.push_back(def);
+
664  }
+
665 
+
668  void addOutput(Print &out, uint16_t channel) {
+
669  Vector<uint16_t> channels;
+
670  channels.push_back(channel);
+
671  ChannelSelectionOutputDef def;
+
672  def.channels = channels;
+
673  def.p_out = &out;
+
674  out_channels.push_back(def);
+
675  }
+
676 
+
679  void addOutput(Print &out, uint16_t left, uint16_t right) {
+
680  Vector<uint16_t> channels;
+
681  channels.push_back(left);
+
682  channels.push_back(right);
+
683  ChannelSelectionOutputDef def;
+
684  def.channels = channels;
+
685  def.p_out = &out;
+
686  out_channels.push_back(def);
+
687  }
+
688 
+
691  void addOutput(AudioOutput &out, uint16_t left, uint16_t right) {
+
692  Vector<uint16_t> channels;
+
693  channels.push_back(left);
+
694  channels.push_back(right);
+
695  ChannelSelectionOutputDef def;
+
696  def.channels = channels;
+
697  def.p_out = &out;
+
698  def.p_audio_info = &out;
+
699  out_channels.push_back(def);
+
700  }
+
701 
+
704  void addOutput(AudioStream &out, uint16_t left, uint16_t right) {
+
705  Vector<uint16_t> channels;
+
706  channels.push_back(left);
+
707  channels.push_back(right);
+
708  ChannelSelectionOutputDef def;
+
709  def.channels = channels;
+
710  def.p_out = &out;
+
711  def.p_audio_info = &out;
+
712  out_channels.push_back(def);
+
713  }
+
714 
+
715  size_t write(const uint8_t *data, size_t len) override {
+
716  if (!is_active) return false;
+
717  LOGD("write %d", (int)len);
+
718  switch (cfg.bits_per_sample) {
+
719  case 16:
+
720  return writeT<int16_t>(data, len);
+
721  case 24:
+
722  return writeT<int24_t>(data, len);
+
723  case 32:
+
724  return writeT<int32_t>(data, len);
+
725  default:
+
726  return 0;
+
727  }
+
728  }
+
729 
+
730  void setAudioInfo(AudioInfo ai) override {
+
731  this->cfg = ai;
+
732  //notifyAudioChange(ai);
+
733  for (auto &info : out_channels) {
+
734  auto p_notify = info.p_audio_info;
+
735  if (p_notify != nullptr) {
+
736  AudioInfo result{ai};
+
737  result.channels = info.channels.size();
+
738  p_notify->setAudioInfo(result);
+
739  }
+
740  }
+
741  }
+
742 
+
743  protected:
+
744  struct ChannelSelectionOutputDef {
+
745  Print *p_out = nullptr;
+
746  AudioInfoSupport *p_audio_info = nullptr;
+
747  SingleBuffer<uint8_t> buffer{CHANNEL_SELECT_BUFFER_SIZE};
+
748  Vector<uint16_t> channels{0};
+
749  };
+
750  Vector<ChannelSelectionOutputDef> out_channels{0};
+
751 
+
752  template <typename T>
+
753  size_t writeT(const uint8_t *buffer, size_t size) {
+
754  if (!is_active) return 0;
+
755  int sample_count = size / sizeof(T);
+
756  //int result_size = sample_count / cfg.channels;
+
757  T *data = (T *)buffer;
+
758 
+
759  for (int i = 0; i < sample_count; i += cfg.channels) {
+
760  T *frame = data + i;
+
761  for (auto &out : out_channels) {
+
762  T out_frame[out.channels.size()] = {0};
+
763  int ch_out = 0;
+
764  for (auto &ch : out.channels) {
+
765  // make sure we have a valid channel
+
766  int channel = (ch < cfg.channels) ? ch : cfg.channels - 1;
+
767  out_frame[ch_out++] = frame[channel];
+
768  }
+
769  // write to buffer
+
770  size_t written = out.buffer.writeArray((const uint8_t *)&out_frame, sizeof(out_frame));
+
771  // write buffer to final output
+
772  if (out.buffer.availableForWrite()<sizeof(out_frame)){
+
773  out.p_out->write(out.buffer.data(), out.buffer.available());
+
774  out.buffer.reset();
+
775  }
+
776  // if (written != sizeof(out_frame)) {
+
777  // LOGW("Could not write all samples %d -> %d", sizeof(out_frame), written);
+
778  // }
+
779  }
+
780  }
+
781  return size;
+
782  }
+
783 
+
785  int getChannels(Print *out, int defaultChannels) {
+
786  for (auto &channels_select : out_channels) {
+
787  if (channels_select.p_out == out) return channels_select.channels.size();
+
788  }
+
789  return defaultChannels;
+
790  }
+
791 };
+
792 
+
793 } // namespace audio_tools
+
Wrapper which converts a AudioStream to a AudioOutput.
Definition: AudioIO.h:283
+
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition: AudioIO.h:304
+
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition: AudioIO.h:291
+
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition: AudioIO.h:293
+
Wrapper which converts a AudioStream to a AudioOutput.
Definition: AudioIO.h:248
+
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition: AudioIO.h:271
+
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition: AudioIO.h:256
+
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition: AudioIO.h:258
+
Wrapper which converts a Print to a AudioOutput.
Definition: AudioIO.h:230
+
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition: AudioIO.h:238
+
void setAudioInfo(AudioInfo info)
Defines the input AudioInfo.
Definition: AudioIO.h:233
virtual void addNotifyAudioChange(AudioInfoSupport &bi)
Adds target to be notified about audio changes.
Definition: AudioTypes.h:160
Supports changes to the sampling rate, bits and channels.
Definition: AudioTypes.h:137
virtual void setAudioInfo(AudioInfo info)=0
Defines the input AudioInfo.
-
Base class for Output Adpapters.
Definition: AudioIO.h:223
+
Base class for Output Adpapters.
Definition: AudioIO.h:224
Abstract Audio Ouptut class.
Definition: AudioOutput.h:22
virtual bool isDeletable()
If true we need to release the related memory in the destructor.
Definition: AudioOutput.h:57
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition: BaseStream.h:109
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition: BaseStream.h:117
-
Flexible functionality to extract one or more channels from a multichannel signal....
Definition: AudioIO.h:618
-
void addOutput(Print &out, uint16_t left, uint16_t right)
Definition: AudioIO.h:678
-
void setAudioInfo(AudioInfo ai) override
Defines the input AudioInfo.
Definition: AudioIO.h:729
-
void addOutput(Print &out, uint16_t channel)
Definition: AudioIO.h:667
-
void addOutput(AudioOutput &out, uint16_t channel)
Definition: AudioIO.h:643
-
int getChannels(Print *out, int defaultChannels)
Determine number of channels for destination.
Definition: AudioIO.h:784
-
void addOutput(AudioStream &out, uint16_t channel)
Definition: AudioIO.h:655
-
void addOutput(AudioStream &out, uint16_t left, uint16_t right)
Definition: AudioIO.h:703
-
void addOutput(AudioOutput &out, uint16_t left, uint16_t right)
Definition: AudioIO.h:690
+
Flexible functionality to extract one or more channels from a multichannel signal....
Definition: AudioIO.h:619
+
void addOutput(Print &out, uint16_t left, uint16_t right)
Definition: AudioIO.h:679
+
void setAudioInfo(AudioInfo ai) override
Defines the input AudioInfo.
Definition: AudioIO.h:730
+
void addOutput(Print &out, uint16_t channel)
Definition: AudioIO.h:668
+
void addOutput(AudioOutput &out, uint16_t channel)
Definition: AudioIO.h:644
+
int getChannels(Print *out, int defaultChannels)
Determine number of channels for destination.
Definition: AudioIO.h:785
+
void addOutput(AudioStream &out, uint16_t channel)
Definition: AudioIO.h:656
+
void addOutput(AudioStream &out, uint16_t left, uint16_t right)
Definition: AudioIO.h:704
+
void addOutput(AudioOutput &out, uint16_t left, uint16_t right)
Definition: AudioIO.h:691
Abstract class: Objects can be put into a pipleline.
Definition: AudioOutput.h:97
Abstract class: Objects can be put into a pipleline.
Definition: AudioStreams.h:69
-
Replicates the output to multiple destinations.
Definition: AudioIO.h:317
-
void add(AudioOutput &out)
Add an additional AudioOutput output.
Definition: AudioIO.h:357
-
void setAudioInfo(AudioInfo info)
Defines the input AudioInfo.
Definition: AudioIO.h:377
-
void add(AudioStream &stream)
Add an AudioStream to the output.
Definition: AudioIO.h:360
-
MultiOutput(AudioStream &out1, AudioStream &out2)
Defines a MultiOutput with 2 final outputs.
Definition: AudioIO.h:336
-
MultiOutput(AudioOutput &out1, AudioOutput &out2)
Defines a MultiOutput with 2 final outputs.
Definition: AudioIO.h:330
-
MultiOutput(AudioOutput &out)
Defines a MultiOutput with a single final outputs,.
Definition: AudioIO.h:325
-
void setOutput(Print &out)
support for Pipleline
Definition: AudioIO.h:409
-
MultiOutput(Print &out1, Print &out2)
Definition: AudioIO.h:343
+
Replicates the output to multiple destinations.
Definition: AudioIO.h:318
+
void add(AudioOutput &out)
Add an additional AudioOutput output.
Definition: AudioIO.h:358
+
void setAudioInfo(AudioInfo info)
Defines the input AudioInfo.
Definition: AudioIO.h:378
+
void add(AudioStream &stream)
Add an AudioStream to the output.
Definition: AudioIO.h:361
+
MultiOutput(AudioStream &out1, AudioStream &out2)
Defines a MultiOutput with 2 final outputs.
Definition: AudioIO.h:337
+
MultiOutput(AudioOutput &out1, AudioOutput &out2)
Defines a MultiOutput with 2 final outputs.
Definition: AudioIO.h:331
+
MultiOutput(AudioOutput &out)
Defines a MultiOutput with a single final outputs,.
Definition: AudioIO.h:326
+
void setOutput(Print &out)
support for Pipleline
Definition: AudioIO.h:410
+
MultiOutput(Print &out1, Print &out2)
Definition: AudioIO.h:344
MultiOutput()=default
Defines a MultiOutput with no final output: Define your outputs with add()
Definition: NoArduino.h:58
virtual bool begin()
Activates the output.
Definition: BaseStream.h:318
Base class for chained converting streams.
Definition: AudioIO.h:142
-
void addNotifyOnFirstWrite()
Add notification on first call of write.
Definition: AudioIO.h:204
virtual void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition: AudioIO.h:144
-
virtual void setOutput(Print &print) override
Defines/Changes the output target.
Definition: AudioIO.h:163
-
void setNotifyOnOutput(AudioInfoSupport &info)
Define potential notification.
Definition: AudioIO.h:201
+
virtual void setOutput(Print &print) override
Defines/Changes the output target.
Definition: AudioIO.h:164
virtual size_t size()
Returns the maximum capacity of the buffer.
Definition: Buffers.h:383
Definition: NoArduino.h:125
-
AudioStream class that can define a start and (an optional) stop time Usually it is used to wrap an A...
Definition: AudioIO.h:421
-
void setEndSec(uint32_t endSeconds)
Definition: AudioIO.h:455
-
void setEndMs(uint32_t ms)
Defines the (optional) end time in milliseconds.
Definition: AudioIO.h:461
-
void setCompressionRatio(float ratio)
Definition: AudioIO.h:541
-
size_t readBytes(uint8_t *data, size_t len) override
Definition: AudioIO.h:495
-
void setStream(Stream &stream)
Defines/Changes the input & output.
Definition: AudioIO.h:550
-
void setStartSec(uint32_t startSeconds)
Definition: AudioIO.h:442
-
int available() override
Provides the available bytes until the end time has reached.
Definition: AudioIO.h:523
-
size_t write(const uint8_t *data, size_t len) override
Plays only data for the indiated start and end time.
Definition: AudioIO.h:515
-
void setStartMs(uint32_t ms)
Defines the start time in milliseconds.
Definition: AudioIO.h:448
-
bool isPlaying()
Returns true if we are in a valid time range and are still playing sound.
Definition: AudioIO.h:467
-
bool isActive()
Returns true if we are not past the end time;.
Definition: AudioIO.h:474
-
void setAudioInfo(AudioInfo info) override
Updates the AudioInfo in the current object and in the source or target.
Definition: AudioIO.h:529
-
void setOutput(Print &out)
Defines/Changes the output target.
Definition: AudioIO.h:548
-
int bytesPerSecond()
Calculates the bytes per second from the AudioInfo.
Definition: AudioIO.h:544
+
AudioStream class that can define a start and (an optional) stop time Usually it is used to wrap an A...
Definition: AudioIO.h:422
+
void setEndSec(uint32_t endSeconds)
Definition: AudioIO.h:456
+
void setEndMs(uint32_t ms)
Defines the (optional) end time in milliseconds.
Definition: AudioIO.h:462
+
void setCompressionRatio(float ratio)
Definition: AudioIO.h:542
+
size_t readBytes(uint8_t *data, size_t len) override
Definition: AudioIO.h:496
+
void setStream(Stream &stream)
Defines/Changes the input & output.
Definition: AudioIO.h:551
+
void setStartSec(uint32_t startSeconds)
Definition: AudioIO.h:443
+
int available() override
Provides the available bytes until the end time has reached.
Definition: AudioIO.h:524
+
size_t write(const uint8_t *data, size_t len) override
Plays only data for the indiated start and end time.
Definition: AudioIO.h:516
+
void setStartMs(uint32_t ms)
Defines the start time in milliseconds.
Definition: AudioIO.h:449
+
bool isPlaying()
Returns true if we are in a valid time range and are still playing sound.
Definition: AudioIO.h:468
+
bool isActive()
Returns true if we are not past the end time;.
Definition: AudioIO.h:475
+
void setAudioInfo(AudioInfo info) override
Updates the AudioInfo in the current object and in the source or target.
Definition: AudioIO.h:530
+
void setOutput(Print &out)
Defines/Changes the output target.
Definition: AudioIO.h:549
+
int bytesPerSecond()
Calculates the bytes per second from the AudioInfo.
Definition: AudioIO.h:545
ConverterStream Helper class which implements the readBytes with the help of write.
Definition: AudioIO.h:23
void begin(T *transform, Stream *source)
setup of the TransformationReader class
Definition: AudioIO.h:29
void restoreOutput(Print *out)
restores the original output in the converter class
Definition: AudioIO.h:131
@@ -830,7 +831,7 @@
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition: AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition: AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition: AudioTypes.h:57
-
Definition: AudioIO.h:743
+
Definition: AudioIO.h:744