arduino-audio-tools
SoundGenerator.h
1 #pragma once
2 
3 #include "AudioTools/CoreAudio/AudioBasic/Collections.h"
4 #include "AudioTools/CoreAudio/AudioLogger.h"
5 #include "AudioTools/CoreAudio/AudioTypes.h"
6 #include <math.h>
7 
14 namespace audio_tools {
15 
25 template <class T> class SoundGenerator {
26 public:
27  SoundGenerator() {
28  info.bits_per_sample = sizeof(T) * 8;
29  }
30 
31  virtual ~SoundGenerator() { end(); }
32 
33  virtual bool begin(AudioInfo info) {
34  this->info = info;
35  return begin();
36  }
37 
38  virtual bool begin() {
39  TRACED();
40  active = true;
41  activeWarningIssued = false;
42  info.logInfo("SoundGenerator:");
43 
44  // support bytes < framesize
45  ring_buffer.resize(info.channels * sizeof(T));
46 
47  return true;
48  }
49 
51  virtual void end() { active = false; }
52 
55  virtual bool isActive() { return active; }
56 
58  virtual T readSample() = 0;
59 
61  virtual size_t readBytes(uint8_t *data, size_t len) {
62  LOGD("readBytes: %d", (int)len);
63  if (!active)
64  return 0;
65  int channels = audioInfo().channels;
66  int frame_size = sizeof(T) * channels;
67  int frames = len / frame_size;
68  if (len >= frame_size) {
69  return readBytesFrames(data, len, frames, channels);
70  }
71  return readBytesFromBuffer(data, len, frame_size, channels);
72  }
73 
76  AudioInfo def;
77  def.bits_per_sample = sizeof(T) * 8;
78  return def;
79  }
80 
82  virtual void setFrequency(float frequency) {
83  LOGE("setFrequency not supported");
84  }
85 
87  virtual AudioInfo audioInfo() { return info; }
88 
90  virtual void setAudioInfo(AudioInfo info) {
91  this->info = info;
92  if (info.bits_per_sample != sizeof(T) * 8) {
93  LOGE("invalid bits_per_sample: %d", info.channels);
94  }
95  }
96 
97 protected:
98  bool active = false;
99  bool activeWarningIssued = false;
100  //int output_channels = 1;
101  AudioInfo info;
102  RingBuffer<uint8_t> ring_buffer{0};
103 
104  size_t readBytesFrames(uint8_t *buffer, size_t lengthBytes, int frames,
105  int channels) {
106  T *result_buffer = (T *)buffer;
107  for (int j = 0; j < frames; j++) {
108  T sample = readSample();
109  for (int ch = 0; ch < channels; ch++) {
110  *result_buffer++ = sample;
111  }
112  }
113  return frames * sizeof(T) * channels;
114  }
115 
116  size_t readBytesFromBuffer(uint8_t *buffer, size_t lengthBytes,
117  int frame_size, int channels) {
118  // fill ringbuffer with one frame
119  if (ring_buffer.isEmpty()) {
120  uint8_t tmp[frame_size];
121  readBytesFrames(tmp, frame_size, 1, channels);
122  ring_buffer.writeArray(tmp, frame_size);
123  }
124  // provide result
125  return ring_buffer.readArray(buffer, lengthBytes);
126  }
127 };
128 
138 template <class T> class SineWaveGenerator : public SoundGenerator<T> {
139 public:
140  // the scale defines the max value which is generated
141  SineWaveGenerator(float amplitude = 0.9f * NumberConverter::maxValueT<T>(),
142  float phase = 0.0f) {
143  LOGD("SineWaveGenerator");
144  m_amplitude = amplitude;
145  m_phase = phase;
146  }
147 
148  bool begin() override {
149  TRACEI();
151  this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
152  return true;
153  }
154 
155  bool begin(AudioInfo info) override {
156  LOGI("%s::begin(channels=%d, sample_rate=%d)", "SineWaveGenerator",
157  (int)info.channels, (int) info.sample_rate);
159  this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
160  return true;
161  }
162 
163  bool begin(AudioInfo info, float frequency) {
164  LOGI("%s::begin(channels=%d, sample_rate=%d, frequency=%.2f)",
165  "SineWaveGenerator", (int)info.channels,(int) info.sample_rate, frequency);
167  this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
168  if (frequency > 0.0f) {
169  setFrequency(frequency);
170  }
171  return true;
172  }
173 
174  bool begin(int channels, int sample_rate, float frequency) {
175  SoundGenerator<T>::info.channels = channels;
176  SoundGenerator<T>::info.sample_rate = sample_rate;
177  return begin(SoundGenerator<T>::info, frequency);
178  }
179 
180  // update m_deltaTime
181  virtual void setAudioInfo(AudioInfo info) override {
183  this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
184  }
185 
186  virtual AudioInfo defaultConfig() override {
188  }
189 
191  void setFrequency(float frequency) override {
192  LOGI("setFrequency: %.2f", frequency);
193  LOGI("active: %s", SoundGenerator<T>::active ? "true" : "false");
194  m_frequency = frequency;
195  }
196 
198  virtual T readSample() override {
199  float angle = double_Pi * m_cycles + m_phase;
200  T result = m_amplitude * sinf(angle);
201  m_cycles += m_frequency * m_deltaTime;
202  if (m_cycles > 1.0f) {
203  m_cycles -= 1.0f;
204  }
205  return result;
206  }
207 
208  void setAmplitude(float amp) { m_amplitude = amp; }
209 
210 protected:
211  volatile float m_frequency = 0.0f;
212  float m_cycles = 0.0f; // Varies between 0.0 and 1.0
213  float m_amplitude = 1.0f;
214  float m_deltaTime = 0.0f;
215  float m_phase = 0.0f;
216  const float double_Pi = PI * 2.0f;
217 
218  void logStatus() {
219  SoundGenerator<T>::info.logStatus();
220  LOGI("amplitude: %f", this->m_amplitude);
221  LOGI("active: %s", SoundGenerator<T>::active ? "true" : "false");
222  }
223 };
224 
225 
233 template <class T> class FastSineGenerator : public SineWaveGenerator<T> {
234 public:
235  FastSineGenerator(float amplitude = 32767.0, float phase = 0.0)
236  : SineWaveGenerator<T>(amplitude, phase) {
237  LOGD("FastSineGenerator");
238  }
239 
240  virtual T readSample() override {
241  float angle =
243  T result = SineWaveGenerator<T>::m_amplitude * sine(angle);
246  if (SineWaveGenerator<T>::m_cycles > 1.0) {
248  }
249  return result;
250  }
251 
252 protected:
254  inline float sine(float t) {
255  float p = (t - (int)t) - 0.5f; // 0 <= p <= 1
256  float pp = p * p;
257  return (p - 6.283211f * pp * p + 9.132843f * pp * pp * p) * -6.221086f;
258  }
259 };
260 
268 template <class T> class SquareWaveGenerator : public FastSineGenerator<T> {
269 public:
270  SquareWaveGenerator(float amplitude = 32767.0f, float phase = 0.0f)
271  : FastSineGenerator<T>(amplitude, phase) {
272  LOGD("SquareWaveGenerator");
273  }
274 
275  virtual T readSample() {
276  return value(FastSineGenerator<T>::readSample(),
278  }
279 
280 protected:
281  // returns amplitude for positive vales and -amplitude for negative values
282  T value(T value, T amplitude) {
283  return (value >= 0) ? amplitude : -amplitude;
284  }
285 };
286 
287 
295 template <class T> class SawToothGenerator : public SineWaveGenerator<T> {
296 public:
297  SawToothGenerator(float amplitude = 32767.0, float phase = 0.0)
298  : SineWaveGenerator<T>(amplitude, phase) {
299  LOGD("SawToothGenerator");
300  }
301 
302  virtual T readSample() override {
303  float angle =
305  T result = SineWaveGenerator<T>::m_amplitude * saw(angle);
308  if (SineWaveGenerator<T>::m_cycles > 1.0) {
310  }
311  return result;
312  }
313 
314 protected:
316  inline float saw(float t) {
317  float p = (t - (int)t) - 0.5f; // 0 <= p <= 1
318  return p;
319  }
320 };
321 
329 template <class T> class WhiteNoiseGenerator : public SoundGenerator<T> {
330 public:
332  WhiteNoiseGenerator(T amplitude = 32767) { this->amplitude = amplitude; }
333 
335  T readSample() { return (random(-amplitude, amplitude)); }
336 
337 protected:
338  T amplitude;
339  // //range : [min, max]
340  int random(int min, int max) { return min + rand() % ((max + 1) - min); }
341 };
342 
350 template <class T> class PinkNoiseGenerator : public SoundGenerator<T> {
351 public:
353  PinkNoiseGenerator(T amplitude = 32767) {
354  this->amplitude = amplitude;
355  max_key = 0x1f; // Five bits set
356  key = 0;
357  for (int i = 0; i < 5; i++)
358  white_values[i] = rand() % (amplitude / 5);
359  }
360 
363  T last_key = key;
364  unsigned int sum;
365 
366  key++;
367  if (key > max_key)
368  key = 0;
369  // Exclusive-Or previous value with current value. This gives
370  // a list of bits that have changed.
371  int diff = last_key ^ key;
372  sum = 0;
373  for (int i = 0; i < 5; i++) {
374  // If bit changed get new random number for corresponding
375  // white_value
376  if (diff & (1 << i))
377  white_values[i] = rand() % (amplitude / 5);
378  sum += white_values[i];
379  }
380  return sum;
381  }
382 
383 protected:
384  T max_key;
385  T key;
386  unsigned int white_values[5];
387  unsigned int amplitude;
388 };
389 
399 template <class T> class SilenceGenerator : public SoundGenerator<T> {
400 public:
401  // the scale defines the max value which is generated
402  SilenceGenerator(T value = 0) { this->value = value; }
403 
406  return value; // return 0
407  }
408 
409 protected:
410  T value;
411 };
412 
420 template <class T> class GeneratorFromStream : public SoundGenerator<T>, public VolumeSupport {
421 public:
423  maxValue = NumberConverter::maxValue(sizeof(T) * 8);
424  };
425 
435  GeneratorFromStream(Stream &input, int channels = 1, float volume = 1.0) {
436  maxValue = NumberConverter::maxValue(sizeof(T) * 8);
437  setStream(input);
438  setVolume(volume);
439  setChannels(channels);
440  }
441 
443  void setStream(Stream &input) { this->p_stream = &input; }
444 
445  void setChannels(int channels) { this->channels = channels; }
446 
449  T data = 0;
450  float total = 0;
451  if (p_stream != nullptr) {
452  for (int j = 0; j < channels; j++) {
453  p_stream->readBytes((uint8_t *)&data, sizeof(T));
454  total += data;
455  }
456  float avg = (total / channels) * volume();
457  if (avg > maxValue) {
458  data = maxValue;
459  } else if (avg < -maxValue) {
460  data = -maxValue;
461  } else {
462  data = avg;
463  }
464  }
465  return data;
466  }
467 
468 protected:
469  Stream *p_stream = nullptr;
470  int channels = 1;
471  float maxValue;
472 };
473 
483 template <class T> class GeneratorFromArray : public SoundGenerator<T> {
484 public:
485  GeneratorFromArray() = default;
498  template <size_t arrayLen>
499  GeneratorFromArray(T (&array)[arrayLen], int repeat = 0,
500  bool setInactiveAtEnd = false, size_t startIndex = 0) {
501  TRACED();
502  this->max_repeat = repeat;
503  this->inactive_at_end = setInactiveAtEnd;
504  this->sound_index = startIndex;
505  setArray(array, arrayLen);
506  }
507 
508  ~GeneratorFromArray() {
509  if (owns_data) {
510  delete[] table;
511  }
512  }
513 
514  template <int arrayLen> void setArray(T (&array)[arrayLen]) {
515  TRACED();
516  setArray(array, arrayLen);
517  }
518 
519  void setArray(T *array, size_t size) {
520  this->table_length = size;
521  this->table = array;
522  LOGI("table_length: %d", (int)size);
523  }
524 
525  virtual bool begin(AudioInfo info) override {
526  return SoundGenerator<T>::begin(info);
527  }
528 
530  bool begin() override {
531  TRACEI();
533  sound_index = 0;
534  repeat_counter = 0;
535  is_running = true;
536  return true;
537  }
538 
540  T readSample() override {
541  // at end deactivate output
542  if (sound_index >= table_length) {
543  // LOGD("reset index - sound_index: %d, table_length:
544  // %d",sound_index,table_length);
545  sound_index = 0;
546  // deactivate when count has been used up
547  if (max_repeat >= 1 && ++repeat_counter >= max_repeat) {
548  LOGD("atEnd");
549  this->is_running = false;
550  if (inactive_at_end) {
551  this->active = false;
552  }
553  }
554  }
555 
556  // LOGD("index: %d - active: %d", sound_index, this->active);
557  T result = 0;
558  if (this->is_running) {
559  result = table[sound_index];
560  sound_index += index_increment;
561  }
562 
563  return result;
564  }
565 
566  // step size the sound index is incremented (default = 1)
567  void setIncrement(int inc) { index_increment = inc; }
568 
569  // Sets up a sine table - returns the effective frequency
570  int setupSine(int sampleRate, float reqFrequency, float amplitude = 1.0) {
571  int sample_count =
572  static_cast<float>(sampleRate) /
573  reqFrequency; // e.g. 44100 / 300hz = 147 samples per wave
574  float angle = 2.0 * PI / sample_count;
575  table = new T[sample_count];
576  for (int j = 0; j < sample_count; j++) {
577  table[j] = sinf(j * angle) * amplitude;
578  }
579  owns_data = true;
580  table_length = sample_count;
581  // calculate effective frequency
582  return sampleRate / sample_count;
583  }
584 
585  // Similar like is active to check if the array is still playing.
586  bool isRunning() { return is_running; }
587 
588 protected:
589  int sound_index = 0;
590  int max_repeat = 0;
591  int repeat_counter = 0;
592  bool inactive_at_end;
593  bool is_running = false;
594  bool owns_data = false;
595  T *table = nullptr;
596  size_t table_length = 0;
597  int index_increment = 1;
598 };
599 
607 template <class T> class GeneratorFixedValue : public SoundGenerator<T> {
608 public:
609  GeneratorFixedValue() = default;
610 
611  virtual bool begin(AudioInfo info) { return SoundGenerator<T>::begin(info); }
612 
613  void setValue(T value) { value_set = value; }
614 
616  bool begin() override {
617  TRACEI();
619  is_running = true;
620  value_return = value_set;
621  return true;
622  }
623 
625  T readSample() override { return value_return; }
626 
627  // Similar like is active to check if the array is still playing.
628  bool isRunning() { return is_running; }
629 
630 protected:
631  T value_set = 0;
632  T value_return = 0;
633  bool is_running = false;
634 };
635 
643 template <class T> class SineFromTable : public SoundGenerator<T> {
644 public:
645  SineFromTable(float amplitude = 32767.0) {
646  this->amplitude = amplitude;
647  this->amplitude_to_be = amplitude;
648  }
649 
651  void setAmplitude(float amplitude) { this->amplitude_to_be = amplitude; }
652 
655  void setMaxAmplitudeStep(float step) { max_amplitude_step = step; }
656 
658  // update angle
659  angle += step;
660  if (angle >= 360.0f) {
661  while (angle >= 360.0f) {
662  angle -= 360.0f;
663  }
664  // update frequency at start of circle (near 0 degrees)
665  step = step_new;
666 
667  updateAmplitudeInSteps();
668  // amplitude = amplitude_to_be;
669  }
670  return interpolate(angle);
671  }
672 
673  bool begin() {
674  is_first = true;
676  base_frequency = SoundGenerator<T>::audioInfo().sample_rate /
677  360.0f; // 122.5 hz (at 44100); 61 hz (at 22050)
678  return true;
679  }
680 
681  bool begin(AudioInfo info, float frequency) {
682  SoundGenerator<T>::begin(info);
683  base_frequency = SoundGenerator<T>::audioInfo().sample_rate /
684  360.0f; // 122.5 hz (at 44100); 61 hz (at 22050)
685  setFrequency(frequency);
686  return true;
687  }
688 
689  bool begin(int channels, int sample_rate, uint16_t frequency = 0) {
690  SoundGenerator<T>::info.channels = channels;
691  SoundGenerator<T>::info.sample_rate = sample_rate;
692  return begin(SoundGenerator<T>::info, frequency);
693  }
694 
695  void setFrequency(float freq) {
696  step_new = freq / base_frequency;
697  if (is_first) {
698  step = step_new;
699  is_first = false;
700  }
701  LOGD("step: %f", step_new);
702  }
703 
704 protected:
705  bool is_first = true;
706  float amplitude;
707  float amplitude_to_be;
708  float max_amplitude_step = 50.0f;
709  float base_frequency = 1.0f;
710  float step = 1.0f;
711  float step_new = 1.0f;
712  float angle = 0.0f;
713  // 122.5 hz (at 44100); 61 hz (at 22050)
714  const float values[181] = {
715  0, 0.0174524, 0.0348995, 0.052336, 0.0697565, 0.0871557,
716  0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809,
717  0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372,
718  0.309017, 0.325568, 0.34202, 0.358368, 0.374607, 0.390731,
719  0.406737, 0.422618, 0.438371, 0.45399, 0.469472, 0.48481,
720  0.5, 0.515038, 0.529919, 0.544639, 0.559193, 0.573576,
721  0.587785, 0.601815, 0.615661, 0.62932, 0.642788, 0.656059,
722  0.669131, 0.681998, 0.694658, 0.707107, 0.71934, 0.731354,
723  0.743145, 0.75471, 0.766044, 0.777146, 0.788011, 0.798636,
724  0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167,
725  0.866025, 0.87462, 0.882948, 0.891007, 0.898794, 0.906308,
726  0.913545, 0.920505, 0.927184, 0.93358, 0.939693, 0.945519,
727  0.951057, 0.956305, 0.961262, 0.965926, 0.970296, 0.97437,
728  0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546,
729  0.994522, 0.996195, 0.997564, 0.99863, 0.999391, 0.999848,
730  1, 0.999848, 0.999391, 0.99863, 0.997564, 0.996195,
731  0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627,
732  0.978148, 0.97437, 0.970296, 0.965926, 0.961262, 0.956305,
733  0.951057, 0.945519, 0.939693, 0.93358, 0.927184, 0.920505,
734  0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.87462,
735  0.866025, 0.857167, 0.848048, 0.838671, 0.829038, 0.819152,
736  0.809017, 0.798636, 0.788011, 0.777146, 0.766044, 0.75471,
737  0.743145, 0.731354, 0.71934, 0.707107, 0.694658, 0.681998,
738  0.669131, 0.656059, 0.642788, 0.62932, 0.615661, 0.601815,
739  0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038,
740  0.5, 0.48481, 0.469472, 0.45399, 0.438371, 0.422618,
741  0.406737, 0.390731, 0.374607, 0.358368, 0.34202, 0.325568,
742  0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951,
743  0.207912, 0.190809, 0.173648, 0.156434, 0.139173, 0.121869,
744  0.104528, 0.0871557, 0.0697565, 0.052336, 0.0348995, 0.0174524,
745  0};
746 
747  T interpolate(float angle) {
748  bool positive = (angle <= 180.0f);
749  float angle_positive = positive ? angle : angle - 180.0f;
750  int angle_int1 = angle_positive;
751  int angle_int2 = angle_int1 + 1;
752  T v1 = values[angle_int1] * amplitude;
753  T v2 = values[angle_int2] * amplitude;
754  T result = v1 < v2 ? map(angle_positive, angle_int1, angle_int2, v1, v2)
755  : map(angle_positive, angle_int1, angle_int2, v2, v1);
756  // float result = v1;
757  return positive ? result : -result;
758  }
759 
760  T map(T x, T in_min, T in_max, T out_min, T out_max) {
761  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
762  }
763 
764  void updateAmplitudeInSteps() {
765  float diff = amplitude_to_be - amplitude;
766  if (abs(diff) > max_amplitude_step) {
767  diff = (diff < 0) ? -max_amplitude_step : max_amplitude_step;
768  }
769  if (abs(diff) >= 1.0f) {
770  amplitude += diff;
771  }
772  }
773 };
774 
782 template <class T> class GeneratorMixer : public SoundGenerator<T> {
783 public:
784  GeneratorMixer() = default;
785 
786  void add(SoundGenerator<T> &generator) { vector.push_back(&generator); }
787  void add(SoundGenerator<T> *generator) { vector.push_back(generator); }
788 
789  void clear() { vector.clear(); }
790 
792  float total = 0.0f;
793  float count = 0.0f;
794  for (auto &generator : vector) {
795  if (generator->isActive()){
796  T sample = generator->readSample();
797  total += sample;
798  count += 1.0f;
799  }
800  }
801  return count > 0.0f ? total / count : 0;
802  }
803 
804 protected:
805  Vector<SoundGenerator<T> *> vector;
806  int actualChannel = 0;
807 };
808 
817 template <class T> class TestGenerator : public SoundGenerator<T> {
818 public:
819  TestGenerator(T max = 1000, T inc = 1) { this->max = max; }
820 
821  T readSample() override {
822  value += inc;
823  if (abs(value) >= max) {
824  inc = -inc;
825  value += (inc * 2);
826  }
827  return value;
828  }
829 
830 protected:
831  T max;
832  T value = 0;
833  T inc = 1;
834 };
835 
836 } // namespace audio_tools
virtual int readArray(T data[], int len)
reads multiple values
Definition: Buffers.h:41
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition: Buffers.h:65
Sine wave which is based on a fast approximation function.
Definition: SoundGenerator.h:233
float sine(float t)
sine approximation.
Definition: SoundGenerator.h:254
virtual T readSample() override
Provides a single sample.
Definition: SoundGenerator.h:240
Just returns a constant value.
Definition: SoundGenerator.h:607
T readSample() override
Provides a single sample.
Definition: SoundGenerator.h:625
bool begin() override
Starts the generation of samples.
Definition: SoundGenerator.h:616
We generate the samples from an array which is provided in the constructor.
Definition: SoundGenerator.h:483
GeneratorFromArray(T(&array)[arrayLen], int repeat=0, bool setInactiveAtEnd=false, size_t startIndex=0)
Construct a new Generator from an array.
Definition: SoundGenerator.h:499
T readSample() override
Provides a single sample.
Definition: SoundGenerator.h:540
bool begin() override
Starts the generation of samples.
Definition: SoundGenerator.h:530
An Adapter Class which lets you use any Stream as a Generator.
Definition: SoundGenerator.h:420
void setStream(Stream &input)
(Re-)Assigns a stream to the Adapter class
Definition: SoundGenerator.h:443
GeneratorFromStream(Stream &input, int channels=1, float volume=1.0)
Constructs a new Generator from a Stream object that can be used e.g. as input for AudioEffectss.
Definition: SoundGenerator.h:435
T readSample()
Provides a single sample from the stream.
Definition: SoundGenerator.h:448
Generator which combines (mixes) multiple sound generators into one output.
Definition: SoundGenerator.h:782
T readSample()
Provides a single sample.
Definition: SoundGenerator.h:791
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition: AudioTypes.h:317
Generates pink noise.
Definition: SoundGenerator.h:350
PinkNoiseGenerator(T amplitude=32767)
the amplitude defines the max value which is generated
Definition: SoundGenerator.h:353
T readSample()
Provides a single sample.
Definition: SoundGenerator.h:362
SawToothGenerator.
Definition: SoundGenerator.h:295
virtual T readSample() override
Provides a single sample.
Definition: SoundGenerator.h:302
float saw(float t)
sine approximation.
Definition: SoundGenerator.h:316
Provides a fixed value (e.g. 0) as sound data. This can be used e.g. to test the output functionality...
Definition: SoundGenerator.h:399
T readSample()
Provides a single sample.
Definition: SoundGenerator.h:405
A sine generator based on a table. The table is created using degrees where one full wave is 360 degr...
Definition: SoundGenerator.h:643
void setFrequency(float freq)
Abstract method: not implemented! Just provides an error message...
Definition: SoundGenerator.h:695
void setAmplitude(float amplitude)
Defines the new amplitude (volume)
Definition: SoundGenerator.h:651
void setMaxAmplitudeStep(float step)
Definition: SoundGenerator.h:655
T readSample()
Provides a single sample.
Definition: SoundGenerator.h:657
Generates a Sound with the help of sin() function. If you plan to change the amplitude or frequency (...
Definition: SoundGenerator.h:138
void setFrequency(float frequency) override
Defines the frequency - after the processing has been started.
Definition: SoundGenerator.h:191
virtual T readSample() override
Provides a single sample.
Definition: SoundGenerator.h:198
virtual void setAudioInfo(AudioInfo info) override
Defines/updates the AudioInfo.
Definition: SoundGenerator.h:181
virtual AudioInfo defaultConfig() override
Provides the default configuration.
Definition: SoundGenerator.h:186
Base class to define the abstract interface for the sound generating classes.
Definition: SoundGenerator.h:25
virtual size_t readBytes(uint8_t *data, size_t len)
Provides the data as byte array with the requested number of channels.
Definition: SoundGenerator.h:61
virtual T readSample()=0
Provides a single sample.
virtual void setFrequency(float frequency)
Abstract method: not implemented! Just provides an error message...
Definition: SoundGenerator.h:82
virtual bool isActive()
Definition: SoundGenerator.h:55
virtual void setAudioInfo(AudioInfo info)
Defines/updates the AudioInfo.
Definition: SoundGenerator.h:90
virtual AudioInfo audioInfo()
Provides the AudioInfo.
Definition: SoundGenerator.h:87
virtual void end()
ends the processing
Definition: SoundGenerator.h:51
virtual AudioInfo defaultConfig()
Provides the default configuration.
Definition: SoundGenerator.h:75
Generates a square wave sound.
Definition: SoundGenerator.h:268
virtual T readSample()
Provides a single sample.
Definition: SoundGenerator.h:275
Definition: NoArduino.h:125
Generates a test signal which is easy to check because the values are incremented or decremented by 1...
Definition: SoundGenerator.h:817
T readSample() override
Provides a single sample.
Definition: SoundGenerator.h:821
Vector implementation which provides the most important methods as defined by std::vector....
Definition: Vector.h:21
Supports the setting and getting of the volume.
Definition: AudioTypes.h:207
virtual float volume()
provides the actual volume in the range of 0.0f to 1.0f
Definition: AudioTypes.h:210
virtual bool setVolume(float volume)
define the actual volume in the range of 0.0f to 1.0f
Definition: AudioTypes.h:212
Generates a random noise sound with the help of rand() function.
Definition: SoundGenerator.h:329
WhiteNoiseGenerator(T amplitude=32767)
the scale defines the max value which is generated
Definition: SoundGenerator.h:332
T readSample()
Provides a single sample.
Definition: SoundGenerator.h:335
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:823
Basic Audio information which drives e.g. I2S.
Definition: AudioTypes.h:52
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition: AudioTypes.h:55
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition: AudioTypes.h:57
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition: AudioTypes.h:59