arduino-audio-tools
AudioStreamsConverter.h
1 #pragma once
2 #include "AudioTools/AudioStreams.h"
3 #include "AudioTools/ResampleStream.h"
4 
5 namespace audio_tools {
6 
13 template <typename T>
15  public:
16  ChannelFormatConverterStreamT(Stream &stream) { setStream(stream); }
17  ChannelFormatConverterStreamT(Print &print) { setStream(print); }
20 
21 
22  bool begin(int fromChannels, int toChannels) {
23  LOGI("begin %d -> %d channels", fromChannels, toChannels);
24  from_channels = fromChannels;
25  to_channels = toChannels;
26  factor = static_cast<float>(toChannels) / static_cast<float>(fromChannels);
27 
28  converter.setSourceChannels(from_channels);
29  converter.setTargetChannels(to_channels);
30 
31  return true;
32  }
33 
34  virtual size_t write(const uint8_t *data, size_t size) override {
35  TRACED();
36  if (from_channels == to_channels) {
37  return p_print->write(data, size);
38  }
39  size_t resultBytes = convert(data, size);
40  assert(resultBytes = factor * size);
41  p_print->write((uint8_t *)buffer.data(), resultBytes);
42  return size;
43  }
44 
45  size_t readBytes(uint8_t *data, size_t size) override {
46  TRACED();
47  if (p_stream == nullptr) return 0;
48  if (from_channels == to_channels) {
49  return p_stream->readBytes(data, size);
50  }
51  size_t in_bytes = 1.0f / factor * size;
52  bufferTmp.resize(in_bytes);
53  p_stream->readBytes(bufferTmp.data(), in_bytes);
54  size_t resultBytes = convert(bufferTmp.data(), in_bytes);
55  assert(size == resultBytes);
56  memcpy(data, (uint8_t *)buffer.data(), size);
57  return size;
58  }
59 
60  void setAudioInfo(AudioInfo cfg) override {
61  AudioStream::setAudioInfo(cfg);
62  to_channels = cfg.channels;
63  }
64 
65  virtual int available() override {
66  return p_stream != nullptr ? p_stream->available() : 0;
67  }
68 
69  virtual int availableForWrite() override {
70  return 1.0f / factor * p_print->availableForWrite();
71  }
72 
73  protected:
74  int from_channels = 2;
75  int to_channels = 2;
76  float factor = 1;
77  Vector<T> buffer{0};
78  Vector<uint8_t> bufferTmp{0};
79  ChannelConverter<T> converter;
80 
81  size_t convert(const uint8_t *in_data, size_t size) {
82  size_t result;
83  size_t result_samples = size / sizeof(T) * factor;
84  buffer.resize(result_samples);
85  result =
86  converter.convert((uint8_t *)buffer.data(), (uint8_t *)in_data, size);
87  if (result != result_samples * sizeof(T)) {
88  LOGE("size %d -> result: %d - expeced: %d", (int)size, (int)result,
89  static_cast<int>(result_samples * sizeof(T)));
90  }
91  return result;
92  }
93 };
94 
102  public:
103  ChannelFormatConverterStream() = default;
104  ChannelFormatConverterStream(Stream &stream) { setStream(stream); }
105  ChannelFormatConverterStream(Print &print) { setStream(print); }
107  ChannelFormatConverterStream &operator=(
108  ChannelFormatConverterStream const &) = delete;
109 
110  void setAudioInfo(AudioInfo cfg) override {
111  AudioStream::setAudioInfo(cfg);
112  switch (bits_per_sample) {
113  case 8:
114  getConverter<int8_t>()->setAudioInfo(cfg);
115  break;
116  case 16:
117  getConverter<int16_t>()->setAudioInfo(cfg);
118  break;
119  case 24:
120  getConverter<int24_t>()->setAudioInfo(cfg);
121  break;
122  case 32:
123  getConverter<int32_t>()->setAudioInfo(cfg);
124  break;
125  }
126  }
127 
128  bool begin(AudioInfo cfg, int toChannels) {
129  AudioStream::setAudioInfo(cfg);
130  LOGI("begin %d -> %d channels", cfg.channels, toChannels);
131  bits_per_sample = cfg.bits_per_sample;
132  bool result = setupConverter(cfg.channels, toChannels);
133  if (!result) {
134  TRACEE()
135  }
136  return result;
137  }
138 
139  virtual size_t write(const uint8_t *data, size_t size) override {
140  LOGD("ChannelFormatConverterStream::write: %d", (int)size);
141  switch (bits_per_sample) {
142  case 8:
143  return getConverter<int8_t>()->write(data, size);
144  case 16:
145  return getConverter<int16_t>()->write(data, size);
146  case 24:
147  return getConverter<int24_t>()->write(data, size);
148  case 32:
149  return getConverter<int32_t>()->write(data, size);
150  default:
151  return 0;
152  }
153  }
154 
155  size_t readBytes(uint8_t *data, size_t size) override {
156  LOGD("ChannelFormatConverterStream::readBytes: %d", (int)size);
157  switch (bits_per_sample) {
158  case 8:
159  return getConverter<int8_t>()->readBytes(data, size);
160  case 16:
161  return getConverter<int16_t>()->readBytes(data, size);
162  case 24:
163  return getConverter<int24_t>()->readBytes(data, size);
164  case 32:
165  return getConverter<int32_t>()->readBytes(data, size);
166  default:
167  return 0;
168  }
169  }
170 
171  virtual int available() override {
172  switch (bits_per_sample) {
173  case 8:
174  return getConverter<int8_t>()->available();
175  case 16:
176  return getConverter<int16_t>()->available();
177  case 24:
178  return getConverter<int24_t>()->available();
179  case 32:
180  return getConverter<int32_t>()->available();
181  default:
182  return 0;
183  }
184  }
185 
186  virtual int availableForWrite() override {
187  switch (bits_per_sample) {
188  case 8:
189  return getConverter<int8_t>()->availableForWrite();
190  case 16:
191  return getConverter<int16_t>()->availableForWrite();
192  case 24:
193  return getConverter<int24_t>()->availableForWrite();
194  case 32:
195  return getConverter<int32_t>()->availableForWrite();
196  default:
197  return 0;
198  }
199  }
200 
201  protected:
202  void *converter;
203  int bits_per_sample = 0;
204 
205  template <typename T>
206  ChannelFormatConverterStreamT<T> *getConverter() {
207  return (ChannelFormatConverterStreamT<T> *)converter;
208  }
209 
210  bool setupConverter(int fromChannels, int toChannels) {
211  bool result = true;
212  if (p_stream != nullptr) {
213  switch (bits_per_sample) {
214  case 8:
215  converter = new ChannelFormatConverterStreamT<int8_t>(*p_stream);
216  getConverter<int8_t>()->begin(fromChannels, toChannels);
217  break;
218  case 16:
219  converter = new ChannelFormatConverterStreamT<int16_t>(*p_stream);
220  getConverter<int16_t>()->begin(fromChannels, toChannels);
221  break;
222  case 24:
223  converter = new ChannelFormatConverterStreamT<int24_t>(*p_stream);
224  getConverter<int24_t>()->begin(fromChannels, toChannels);
225  break;
226  case 32:
227  converter = new ChannelFormatConverterStreamT<int32_t>(*p_stream);
228  getConverter<int32_t>()->begin(fromChannels, toChannels);
229  break;
230  default:
231  result = false;
232  }
233  } else {
234  switch (bits_per_sample) {
235  case 8:
236  converter = new ChannelFormatConverterStreamT<int8_t>(*p_print);
237  getConverter<int8_t>()->begin(fromChannels, toChannels);
238  break;
239  case 16:
240  converter = new ChannelFormatConverterStreamT<int16_t>(*p_print);
241  getConverter<int16_t>()->begin(fromChannels, toChannels);
242  break;
243  case 24:
244  converter = new ChannelFormatConverterStreamT<int24_t>(*p_print);
245  getConverter<int24_t>()->begin(fromChannels, toChannels);
246  break;
247  case 32:
248  converter = new ChannelFormatConverterStreamT<int32_t>(*p_print);
249  getConverter<int32_t>()->begin(fromChannels, toChannels);
250  break;
251  default:
252  result = false;
253  }
254  }
255  return result;
256  }
257 };
258 
271 template <typename TFrom, typename TTo>
273  public:
274  NumberFormatConverterStreamT() = default;
275  NumberFormatConverterStreamT(Stream &stream) { setStream(stream); }
276  NumberFormatConverterStreamT(Print &print) { setStream(print); }
277 
278  bool begin() override {
279  LOGI("begin %d -> %d bits", (int) sizeof(TFrom),(int) sizeof(TTo));
280  return true;
281  }
282 
283  virtual size_t write(const uint8_t *data, size_t size) override {
284  TRACED();
285  if (sizeof(TFrom) == sizeof(TTo)) return p_print->write(data, size);
286  size_t samples = size / sizeof(TFrom);
287  size_t result_size = 0;
288  TFrom *data_source = (TFrom *)data;
289 
290  if (!is_buffered) {
291  for (size_t j = 0; j < samples; j++) {
292  TTo value = NumberConverter::convert<TFrom, TTo>(data_source[j]);
293  result_size += p_print->write((uint8_t *)&value, sizeof(TTo));
294  }
295  } else {
296  buffer.resize(sizeof(TTo) * samples);
297  for (size_t j = 0; j < samples; j++) {
298  TTo value = NumberConverter::convert<TFrom, TTo>(data_source[j]);
299  result_size += buffer.writeArray((uint8_t *)&value, sizeof(TTo));
300  }
301  p_print->write((uint8_t *)buffer.address(), result_size);
302  buffer.reset();
303  }
304 
305  return size;
306  }
307 
308  size_t readBytes(uint8_t *data, size_t size) override {
309  LOGD("NumberFormatConverterStreamT::readBytes: %d", (int)size);
310  if (p_stream == nullptr) return 0;
311  size_t samples = size / sizeof(TTo);
312  TTo *data_target = (TTo *)data;
313  TFrom source;
314  if (!is_buffered) {
315  for (size_t j = 0; j < samples; j++) {
316  source = 0;
317  p_stream->readBytes((uint8_t *)&source, sizeof(TFrom));
318  data_target[j] = NumberConverter::convert<TFrom, TTo>(source);
319  }
320  } else {
321  buffer.resize(sizeof(TFrom) * samples);
322  readSamples<TFrom>(p_stream, (TFrom *)buffer.address(), samples);
323  TFrom *data = (TFrom *)buffer.address();
324  for (size_t j = 0; j < samples; j++) {
325  data_target[j] = NumberConverter::convert<TFrom, TTo>(data[j]);
326  }
327  }
328  return size;
329  }
330 
331  virtual int available() override {
332  return p_stream != nullptr ? p_stream->available() : 0;
333  }
334 
335  virtual int availableForWrite() override {
336  return p_print->availableForWrite();
337  }
338 
341  void setBuffered(bool flag) { is_buffered = flag; }
342 
343  protected:
344  SingleBuffer<uint8_t> buffer{0};
345  bool is_buffered = false;
346 };
347 
357  public:
358  NumberFormatConverterStream() = default;
359  NumberFormatConverterStream(Stream &stream) { setStream(stream); }
360  NumberFormatConverterStream(Print &print) { setStream(print); }
361 
362  void setAudioInfo (AudioInfo info) override {
363  this->from_bit_per_samples = info.sample_rate;
364  AudioStream::setAudioInfo(info);
365  }
366 
367  bool begin(AudioInfo info, int to_bit_per_samples) {
368  AudioStream::setAudioInfo(info);
369  return begin(info.bits_per_sample, to_bit_per_samples);
370  }
371 
372  bool begin(int from_bit_per_samples, int to_bit_per_samples) {
373  LOGI("begin %d -> %d bits", from_bit_per_samples, to_bit_per_samples);
374  bool result = true;
375  this->from_bit_per_samples = from_bit_per_samples;
376  this->to_bit_per_samples = to_bit_per_samples;
377 
378  if (from_bit_per_samples == to_bit_per_samples) {
379  LOGI("no bit conversion: %d -> %d", from_bit_per_samples,
380  to_bit_per_samples);
381  } else if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
383  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
385  } else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
387  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
389  } else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
391  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
393  } else {
394  result = false;
395  LOGE("bit combination not supported %d -> %d", from_bit_per_samples,
396  to_bit_per_samples);
397  }
398 
399  if (from_bit_per_samples != to_bit_per_samples){
400  setupStream();
401  }
402 
403  if (!result) {
404  TRACEE()
405  }
406  return result;
407  }
408 
409  virtual size_t write(const uint8_t *data, size_t size) override {
410  LOGD("NumberFormatConverterStream::write: %d", (int) size);
411  if (from_bit_per_samples == to_bit_per_samples) {
412  return p_print->write(data, size);
413  }
414 
415  if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
416  return getConverter<int8_t, int16_t>()->write(data, size);
417  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
418  return getConverter<int16_t, int8_t>()->write(data, size);
419  } else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
420  return getConverter<int24_t, int16_t>()->write(data, size);
421  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
422  return getConverter<int16_t, int24_t>()->write(data, size);
423  } else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
424  return getConverter<int32_t, int16_t>()->write(data, size);
425  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
426  return getConverter<int16_t, int32_t>()->write(data, size);
427  } else {
428  TRACEE();
429  return 0;
430  }
431  }
432 
433  size_t readBytes(uint8_t *data, size_t size) override {
434  LOGD("NumberFormatConverterStream::readBytes: %d", (int)size);
435  if (from_bit_per_samples == to_bit_per_samples) {
436  return p_stream->readBytes(data, size);
437  }
438  if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
439  return getConverter<int8_t, int16_t>()->readBytes(data, size);
440  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
441  return getConverter<int16_t, int8_t>()->readBytes(data, size);
442  } else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
443  return getConverter<int24_t, int16_t>()->readBytes(data, size);
444  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
445  return getConverter<int16_t, int24_t>()->readBytes(data, size);
446  } else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
447  return getConverter<int32_t, int16_t>()->readBytes(data, size);
448  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
449  return getConverter<int16_t, int32_t>()->readBytes(data, size);
450  } else {
451  TRACEE();
452  return 0;
453  }
454  }
455 
456  virtual int available() override {
457  if (from_bit_per_samples == to_bit_per_samples) {
458  return p_stream->available();
459  }
460  if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
461  return getConverter<int8_t, int16_t>()->available();
462  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
463  return getConverter<int16_t, int8_t>()->available();
464  } else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
465  return getConverter<int24_t, int16_t>()->available();
466  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
467  return getConverter<int16_t, int24_t>()->available();
468  } else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
469  return getConverter<int32_t, int16_t>()->available();
470  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
471  return getConverter<int16_t, int32_t>()->available();
472  } else {
473  TRACEE();
474  return 0;
475  }
476  }
477 
478  virtual int availableForWrite() override {
479  if (from_bit_per_samples == to_bit_per_samples) {
480  return p_print->availableForWrite();
481  }
482  if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
483  return getConverter<int8_t, int16_t>()->availableForWrite();
484  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
485  return getConverter<int16_t, int8_t>()->availableForWrite();
486  } else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
487  return getConverter<int24_t, int16_t>()->availableForWrite();
488  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
489  return getConverter<int16_t, int24_t>()->availableForWrite();
490  } else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
491  return getConverter<int32_t, int16_t>()->availableForWrite();
492  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
493  return getConverter<int16_t, int32_t>()->availableForWrite();
494  } else {
495  TRACEE();
496  return 0;
497  }
498  }
499 
500  void setBuffered(bool flag) {
501  if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
502  getConverter<int8_t, int16_t>()->setBuffered(flag);
503  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
504  getConverter<int16_t, int8_t>()->setBuffered(flag);
505  } else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
506  getConverter<int24_t, int16_t>()->setBuffered(flag);
507  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
508  getConverter<int16_t, int24_t>()->setBuffered(flag);
509  } else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
510  getConverter<int32_t, int16_t>()->setBuffered(flag);
511  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
512  getConverter<int16_t, int32_t>()->setBuffered(flag);
513  }
514  }
515 
516  protected:
517  void *converter = nullptr;
518  int from_bit_per_samples = 0;
519  int to_bit_per_samples = 0;
520 
521  template <typename TFrom, typename TTo>
523  return (NumberFormatConverterStreamT<TFrom, TTo> *)converter;
524  }
525 
526  void setupStream() {
527  if (p_stream != nullptr) {
528  if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
529  getConverter<int8_t, int16_t>()->setStream(*p_stream);
530  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
531  getConverter<int16_t, int8_t>()->setStream(*p_stream);
532  } else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
533  getConverter<int24_t, int16_t>()->setStream(*p_stream);
534  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
535  getConverter<int16_t, int24_t>()->setStream(*p_stream);
536  } else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
537  getConverter<int32_t, int16_t>()->setStream(*p_stream);
538  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
539  getConverter<int16_t, int32_t>()->setStream(*p_stream);
540  } else {
541  TRACEE();
542  }
543  } else {
544  if (from_bit_per_samples == 8 && to_bit_per_samples == 16) {
545  getConverter<int8_t, int16_t>()->setStream(*p_print);
546  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 8) {
547  getConverter<int16_t, int8_t>()->setStream(*p_print);
548  } else if (from_bit_per_samples == 24 && to_bit_per_samples == 16) {
549  getConverter<int24_t, int16_t>()->setStream(*p_print);
550  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 24) {
551  getConverter<int16_t, int24_t>()->setStream(*p_print);
552  } else if (from_bit_per_samples == 32 && to_bit_per_samples == 16) {
553  getConverter<int32_t, int16_t>()->setStream(*p_print);
554  } else if (from_bit_per_samples == 16 && to_bit_per_samples == 32) {
555  getConverter<int16_t, int32_t>()->setStream(*p_print);
556  } else {
557  TRACEE();
558  }
559  }
560  }
561 };
562 
572  public:
573  FormatConverterStream() = default;
574  FormatConverterStream(Stream &stream) { setStream(stream); }
575  FormatConverterStream(Print &print) { setStream(print); }
577  setSourceAudioInfo(stream.audioInfo());
578  setStream(stream);
579  }
581  setSourceAudioInfo(print.audioInfo());
582  setStream(print);
583  }
584 
585  void setStream(Stream &io) override {
586  TRACED();
587  //p_print = &print;
588  ReformatBaseStream::setStream(io);
589  sampleRateConverter.setStream(io);
590  }
591 
592  void setStream(Print &print) override {
593  TRACED();
594  //p_print = &print;
595  ReformatBaseStream::setStream(print);
596  sampleRateConverter.setStream(print);
597  }
598 
599 
602  void setSourceAudioInfo(AudioInfo from) { from_cfg = from; }
603 
604  bool begin(AudioInfo from, AudioInfo to) {
605  setSourceAudioInfo(from);
606  return begin(to);
607  }
608 
609  bool begin(AudioInfo to) {
610  TRACED();
611  setAudioInfo(to);
612  to_cfg = to;
613 
614  // build output chain
615  if (getStream()!=nullptr){
616  sampleRateConverter.setStream(*getStream());
617  }
618  if(getPrint()!=nullptr){
619  sampleRateConverter.setStream(*getPrint());
620  }
621  numberFormatConverter.setStream(sampleRateConverter);
622  channelFormatConverter.setStream(numberFormatConverter);
623 
624  // start individual converters
625  bool result = channelFormatConverter.begin(from_cfg, to_cfg.channels);
626 
627  AudioInfo from_actual_cfg(from_cfg);
628  from_actual_cfg.channels = to_cfg.channels;
629  result &= numberFormatConverter.begin(from_actual_cfg.bits_per_sample,
630  to_cfg.bits_per_sample);
631 
632  numberFormatConverter.setBuffered(is_buffered);
633  sampleRateConverter.setBuffered(is_buffered);
634 
635 
636  from_actual_cfg.bits_per_sample = to_cfg.bits_per_sample;
637  result &= sampleRateConverter.begin(from_actual_cfg, to_cfg.sample_rate);
638 
639  // setup reader to support readBytes()
640  if (getStream()!=nullptr){
641  setupReader();
642  }
643 
644  if (!result) {
645  LOGE("begin failed");
646  }
647  return result;
648  }
649 
650  virtual size_t write(const uint8_t *data, size_t size) override {
651  LOGD("FormatConverterStream::write: %d", (int)size);
652  return channelFormatConverter.write(data, size);
653  }
654 
656  void setBuffered(bool active){
657  is_buffered = active;
658  }
659 
660  protected:
661  AudioInfo from_cfg;
662  AudioInfo to_cfg;
663  NumberFormatConverterStream numberFormatConverter;
664  ChannelFormatConverterStream channelFormatConverter;
665  ResampleStream sampleRateConverter;
666  bool is_buffered = true;
667 
670  float byteFactor() {
671  return (float)from_cfg.channels / (float)to_cfg.channels *
672  (float)from_cfg.bits_per_sample / (float)to_cfg.bits_per_sample;
673  }
674 };
675 
676 } // namespace audio_tools
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: AudioStreams.h:47
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition: Buffers.h:61
Increasing or decreasing the number of channels.
Definition: BaseConverter.h:653
Channel converter which does not use a template.
Definition: AudioStreamsConverter.h:101
Converter for reducing or increasing the number of Channels.
Definition: AudioStreamsConverter.h:14
Converter which converts bits_per_sample, channels and the sample_rate. The conversion is supported b...
Definition: AudioStreamsConverter.h:571
void setBuffered(bool active)
Buffering is active by default to minimize the number of output calls.
Definition: AudioStreamsConverter.h:656
void setSourceAudioInfo(AudioInfo from)
Definition: AudioStreamsConverter.h:602
float byteFactor()
Definition: AudioStreamsConverter.h:670
Converter which converts between bits_per_sample and 16 bits. The templated NumberFormatConverterStre...
Definition: AudioStreamsConverter.h:356
Converter which converts from source bits_per_sample to target bits_per_sample.
Definition: AudioStreamsConverter.h:272
void setBuffered(bool flag)
Definition: AudioStreamsConverter.h:341
Definition: NoArduino.h:51
Base class for chained converting streams.
Definition: ResampleStream.h:133
Dynamic Resampling. We can use a variable factor to speed up or slow down the playback.
Definition: ResampleStream.h:191
void setBuffered(bool active)
Activates buffering to avoid small incremental writes.
Definition: ResampleStream.h:299
T * address() override
Provides address to beginning of the buffer.
Definition: Buffers.h:237
void reset() override
clears the buffer
Definition: Buffers.h:242
Definition: NoArduino.h:114
Vector implementation which provides the most important methods as defined by std::vector....
Definition: Vector.h:18
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AnalogAudio.h:9
Basic Audio information which drives e.g. I2S.
Definition: AudioTypes.h:43