arduino-audio-tools
Loading...
Searching...
No Matches
SoundGenerator.h
1#pragma once
2
3#include <math.h>
4
5#include "AudioTools/CoreAudio/AudioBasic/Collections.h"
6#include "AudioTools/CoreAudio/AudioLogger.h"
7#include "AudioTools/CoreAudio/AudioTypes.h"
8#include "AudioTools/CoreAudio/Buffers.h"
9
16namespace audio_tools {
17
27template <class T = int16_t>
29 public:
30 SoundGenerator() { info.bits_per_sample = sizeof(T) * 8; }
31
32 virtual ~SoundGenerator() { end(); }
33
34 virtual bool begin(AudioInfo info) {
35 this->info = info;
36 return begin();
37 }
38
39 virtual bool begin() {
40 TRACED();
41 active = true;
42 activeWarningIssued = false;
43 info.logInfo("SoundGenerator:");
44
45 // support bytes < framesize
46 ring_buffer.resize(info.channels * sizeof(T));
47
48 return true;
49 }
50
52 virtual void end() { active = false; }
53
56 virtual bool isActive() { return active; }
57
59 virtual T readSample() = 0;
60
62 virtual size_t readBytes(uint8_t* data, size_t len) {
63 LOGD("readBytes: %d", (int)len);
64 if (!active) 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 recalculatePlayTime();
96 }
97
98 void setPlayTime(uint32_t playMs, uint8_t upPercent = 20,
99 uint8_t downPercent = 30) {
100 LOGI("setPlayTime: playMs=%d, upPercent=%d, downPercent=%d", playMs,
101 upPercent, downPercent);
102 this->playMs = playMs;
103 this->upPercent = upPercent;
104 this->downPercent = downPercent;
105 currentSample = 0;
106 recalculatePlayTime();
107 factor = 0.0f;
108 }
109
110 protected:
111 bool active = false;
112 bool activeWarningIssued = false;
113 // int output_channels = 1;
114 AudioInfo info;
115 RingBuffer<uint8_t> ring_buffer{0};
116 uint32_t playMs = 0;
117 uint8_t upPercent = 5;
118 uint8_t downPercent = 40;
119 uint32_t playSamples = 0;
120 uint32_t upSamples = 0;
121 uint32_t rampDownSamples = 0;
122 float rampUpInc = 0.0;
123 float rampDownDec = 0.0;
124 float factor = 1.0f;
125 uint32_t currentSample = 0;
126
127 void recalculatePlayTime() {
128 if (upPercent + downPercent > 100) {
129 downPercent = 100 - upPercent;
130 }
131 playSamples = info.sample_rate / 1000 * playMs;
132 upSamples = (playSamples * upPercent) / 100;
133 rampDownSamples = (playSamples * downPercent) / 100;
134 rampUpInc = 0;
135 if (upSamples > 0) {
136 rampUpInc = 1.0f / upSamples;
137 }
138 rampDownDec = 0;
139 if (rampDownSamples > 0) {
140 rampDownDec = 1.0f / rampDownSamples;
141 }
142 }
143
144 size_t readBytesFrames(uint8_t* buffer, size_t lengthBytes, int frames,
145 int channels) {
146 T* result_buffer = (T*)buffer;
147 int frames_written = 0;
148 if (playMs > 0 && currentSample > playSamples) {
149 return 0;
150 }
151
152 for (int j = 0; j < frames; j++) {
153 T sample = readSample();
154
155 // if we requested a play time
156 if (playMs > 0) {
157 currentSample++;
158 sample = applyRamp(sample);
159 }
160
161 for (int ch = 0; ch < channels; ch++) {
162 *result_buffer++ = sample;
163 }
164
165 frames_written++;
166 // exit loop if we have reached the requested play time
167 if (playMs > 0 && currentSample > playSamples) {
168 break;
169 }
170 }
171 return frames_written * sizeof(T) * channels;
172 }
173
174 // Applies ramp up and ramp down logic to the sample
175 T applyRamp(T sample) {
176 // Ramp up
177 if (rampUpInc > 0 && currentSample <= upSamples) {
178 factor += rampUpInc;
179 if (factor > 1.0f) {
180 factor = 1.0f;
181 }
182 }
183 // Ramp down
184 else if (rampDownDec > 0 && currentSample >= playSamples - rampDownSamples) {
185 factor -= rampDownDec;
186 if (factor < 0.0f) {
187 factor = 0.0f;
188 }
189 }
190 // Sustain
191 else {
192 factor = 1.0f;
193 }
194 return (T)(factor * sample);
195 }
196
197 size_t readBytesFromBuffer(uint8_t* buffer, size_t lengthBytes,
198 int frame_size, int channels) {
199 // fill ringbuffer with one frame
200 if (ring_buffer.isEmpty()) {
201 uint8_t tmp[frame_size];
202 readBytesFrames(tmp, frame_size, 1, channels);
203 ring_buffer.writeArray(tmp, frame_size);
204 }
205 // provide result
206 return ring_buffer.readArray(buffer, lengthBytes);
207 }
208};
209
219template <class T = int16_t>
221 public:
222 // the scale defines the max value which is generated
223 SineWaveGenerator(float amplitude = 0.9f * NumberConverter::maxValueT<T>(),
224 float phase = 0.0f) {
225 LOGD("SineWaveGenerator");
226 m_amplitude = amplitude;
227 m_phase = phase;
228 }
229
230 bool begin() override {
231 TRACEI();
233 this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
234 return true;
235 }
236
237 bool begin(AudioInfo info) override {
238 LOGI("%s::begin(channels=%d, sample_rate=%d)", "SineWaveGenerator",
239 (int)info.channels, (int)info.sample_rate);
241 this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
242 return true;
243 }
244
245 bool begin(AudioInfo info, float frequency) {
246 LOGI("%s::begin(channels=%d, sample_rate=%d, frequency=%.2f)",
247 "SineWaveGenerator", (int)info.channels, (int)info.sample_rate,
248 frequency);
250 this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
251 if (frequency > 0.0f) {
252 setFrequency(frequency);
253 }
254 return true;
255 }
256
257 bool begin(int channels, int sample_rate, float frequency) {
258 SoundGenerator<T>::info.channels = channels;
259 SoundGenerator<T>::info.sample_rate = sample_rate;
260 return begin(SoundGenerator<T>::info, frequency);
261 }
262
263 // update m_deltaTime
264 virtual void setAudioInfo(AudioInfo info) override {
266 this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
267 }
268
269 virtual AudioInfo defaultConfig() override {
271 }
272
274 void setFrequency(float frequency) override {
275 LOGI("setFrequency: %.2f", frequency);
276 LOGI("active: %s", SoundGenerator<T>::active ? "true" : "false");
277 if (m_frequency != frequency) {
278 m_cycles = 0.0f; // reset cycles to avoid phase jumps
279 m_phase = 0.0f; // reset phase to avoid jumps
280 }
281 m_frequency = frequency;
282 }
283
285 virtual T readSample() override {
286 float angle = double_Pi * m_cycles + m_phase;
287 T result = m_amplitude * sinf(angle);
288 m_cycles += m_frequency * m_deltaTime;
289 if (m_cycles > 1.0f) {
290 m_cycles -= 1.0f;
291 }
292 return result;
293 }
294
295 void setAmplitude(float amp) { m_amplitude = amp; }
296
297 protected:
298 volatile float m_frequency = 0.0f;
299 float m_cycles = 0.0f; // Varies between 0.0 and 1.0
300 float m_amplitude = 1.0f;
301 float m_deltaTime = 0.0f;
302 float m_phase = 0.0f;
303 const float double_Pi = 2.0f * PI;
304
305 void logStatus() {
306 SoundGenerator<T>::info.logStatus();
307 LOGI("amplitude: %f", this->m_amplitude);
308 LOGI("active: %s", SoundGenerator<T>::active ? "true" : "false");
309 }
310};
311
319template <class T = int16_t>
321 public:
322 FastSineGenerator(float amplitude = 32767.0, float phase = 0.0)
323 : SineWaveGenerator<T>(amplitude, phase) {
324 LOGD("FastSineGenerator");
325 }
326
338
339 protected:
341 inline float sine(float t) {
342 float p = (t - (int)t) - 0.5f; // 0 <= p <= 1
343 float pp = p * p;
344 return (p - 6.283211f * pp * p + 9.132843f * pp * pp * p) * -6.221086f;
345 }
346};
347
355template <class T = int16_t>
357 public:
358 SquareWaveGenerator(float amplitude = 32767.0f, float phase = 0.0f)
359 : FastSineGenerator<T>(amplitude, phase) {
360 LOGD("SquareWaveGenerator");
361 }
362
367
368 protected:
369 // returns amplitude for positive vales and -amplitude for negative values
370 T value(T value, T amplitude) {
371 return (value >= 0) ? amplitude : -amplitude;
372 }
373};
374
382template <class T = int16_t>
384 public:
385 SawToothGenerator(float amplitude = 32767.0, float phase = 0.0)
386 : SineWaveGenerator<T>(amplitude, phase) {
387 LOGD("SawToothGenerator");
388 }
389
401
402 protected:
404 inline float saw(float t) {
405 float p = (t - (int)t) - 0.5f; // 0 <= p <= 1
406 return p;
407 }
408};
409
417template <class T = int16_t>
419 public:
421 WhiteNoiseGenerator(T amplitude = 32767) { this->amplitude = amplitude; }
422
424 T readSample() { return (random(-amplitude, amplitude)); }
425
426 protected:
427 T amplitude;
428 // //range : [min, max]
429 int random(int min, int max) { return min + rand() % ((max + 1) - min); }
430};
431
439template <class T = int16_t>
441 public:
443 PinkNoiseGenerator(T amplitude = 32767) {
444 this->amplitude = amplitude;
445 max_key = 0x1f; // Five bits set
446 key = 0;
447 for (int i = 0; i < 5; i++) white_values[i] = rand() % (amplitude / 5);
448 }
449
452 T last_key = key;
453 unsigned int sum;
454
455 key++;
456 if (key > max_key) key = 0;
457 // Exclusive-Or previous value with current value. This gives
458 // a list of bits that have changed.
459 int diff = last_key ^ key;
460 sum = 0;
461 for (int i = 0; i < 5; i++) {
462 // If bit changed get new random number for corresponding
463 // white_value
464 if (diff & (1 << i)) white_values[i] = rand() % (amplitude / 5);
465 sum += white_values[i];
466 }
467 return sum;
468 }
469
470 protected:
471 T max_key;
472 T key;
473 unsigned int white_values[5];
474 unsigned int amplitude;
475};
476
486template <class T = int16_t>
488 public:
489 // the scale defines the max value which is generated
490 SilenceGenerator(T value = 0) { this->value = value; }
491
494 return value; // return 0
495 }
496
497 protected:
498 T value;
499};
500
508template <class T = int16_t>
510 public:
512 maxValue = NumberConverter::maxValue(sizeof(T) * 8);
513 };
514
524 GeneratorFromStream(Stream& input, int channels = 1, float volume = 1.0) {
525 maxValue = NumberConverter::maxValue(sizeof(T) * 8);
526 setStream(input);
528 setChannels(channels);
529 }
530
532 void setStream(Stream& input) { this->p_stream = &input; }
533
534 void setChannels(int channels) { this->channels = channels; }
535
538 T data = 0;
539 float total = 0;
540 if (p_stream != nullptr) {
541 for (int j = 0; j < channels; j++) {
542 p_stream->readBytes((uint8_t*)&data, sizeof(T));
543 total += data;
544 }
545 float avg = (total / channels) * volume();
546 if (avg > maxValue) {
547 data = maxValue;
548 } else if (avg < -maxValue) {
549 data = -maxValue;
550 } else {
551 data = avg;
552 }
553 }
554 return data;
555 }
556
557 protected:
558 Stream* p_stream = nullptr;
559 int channels = 1;
560 float maxValue;
561};
562
572template <class T = int16_t>
574 public:
575 GeneratorFromArray() = default;
588 template <size_t arrayLen>
589 GeneratorFromArray(T (&array)[arrayLen], int repeat = 0,
590 bool setInactiveAtEnd = false, size_t startIndex = 0) {
591 TRACED();
592 this->max_repeat = repeat;
593 this->inactive_at_end = setInactiveAtEnd;
594 this->sound_index = startIndex;
595 setArray(array, arrayLen);
596 }
597
598 template <int arrayLen>
599 void setArray(T (&array)[arrayLen]) {
600 TRACED();
601 setArray(array, arrayLen);
602 }
603
604 void setArray(T* array, size_t size) {
605 table.resize(size);
606 for (int j = 0; j < size; j++) {
607 table[j] = array[j];
608 }
609 LOGI("table_length: %d", (int)size);
610 }
611
612 virtual bool begin(AudioInfo info) override {
613 return SoundGenerator<T>::begin(info);
614 }
615
617 bool begin() override {
618 TRACEI();
620 sound_index = 0;
621 repeat_counter = 0;
622 is_running = true;
623 return true;
624 }
625
626 void end() override { table.resize(0); }
627
629 T readSample() override {
630 // at end deactivate output
631 if (sound_index >= table.size()) {
632 // LOGD("reset index - sound_index: %d, table_length:
633 // %d",sound_index,table_length);
634 sound_index = 0;
635 // deactivate when count has been used up
636 if (max_repeat >= 1 && ++repeat_counter >= max_repeat) {
637 LOGD("atEnd");
638 this->is_running = false;
639 if (inactive_at_end) {
640 this->active = false;
641 }
642 }
643 }
644
645 // LOGD("index: %d - active: %d", sound_index, this->active);
646 T result = 0;
647 if (this->is_running) {
648 result = table[sound_index];
649 sound_index += index_increment;
650 }
651
652 return result;
653 }
654
655 // step size the sound index is incremented (default = 1)
656 void setIncrement(int inc) { index_increment = inc; }
657
658 // Sets up a sine table - returns the effective frequency
659 int setupSine(int sampleRate, float reqFrequency, float amplitude = 1.0) {
660 int sample_count =
661 static_cast<float>(sampleRate) /
662 reqFrequency; // e.g. 44100 / 300hz = 147 samples per wave
663 float angle = 2.0 * PI / sample_count;
664 table.resize(sample_count);
665 for (int j = 0; j < sample_count; j++) {
666 table[j] = sinf(j * angle) * amplitude;
667 }
668 // calculate effective frequency
669 return sampleRate / sample_count;
670 }
671
672 // Similar like is active to check if the array is still playing.
673 bool isRunning() { return is_running; }
674
675 protected:
676 int sound_index = 0;
677 int max_repeat = 0;
678 int repeat_counter = 0;
679 bool inactive_at_end;
680 bool is_running = false;
681 bool owns_data = false;
682 Vector<T> table;
683 int index_increment = 1;
684};
685
693template <class T = int16_t>
695 public:
696 GeneratorFixedValue() = default;
697
698 virtual bool begin(AudioInfo info) { return SoundGenerator<T>::begin(info); }
699
700 void setValue(T value) { value_set = value; }
701
703 bool begin() override {
704 TRACEI();
706 is_running = true;
707 value_return = value_set;
708 return true;
709 }
710
712 T readSample() override { return value_return; }
713
714 // Similar like is active to check if the array is still playing.
715 bool isRunning() { return is_running; }
716
717 protected:
718 T value_set = 0;
719 T value_return = 0;
720 bool is_running = false;
721};
722
730template <class T = int16_t>
731class SineFromTable : public SoundGenerator<T> {
732 public:
733 SineFromTable(float amplitude = 32767.0) {
734 this->amplitude = amplitude;
735 this->amplitude_to_be = amplitude;
736 }
737
739 void setAmplitude(float amplitude) { this->amplitude_to_be = amplitude; }
740
743 void setMaxAmplitudeStep(float step) { max_amplitude_step = step; }
744
746 // update angle
747 angle += step;
748 if (angle >= 360.0f) {
749 while (angle >= 360.0f) {
750 angle -= 360.0f;
751 }
752 // update frequency at start of circle (near 0 degrees)
753 step = step_new;
754
755 updateAmplitudeInSteps();
756 // amplitude = amplitude_to_be;
757 }
758 return interpolate(angle);
759 }
760
761 bool begin() {
762 is_first = true;
764 base_frequency = SoundGenerator<T>::audioInfo().sample_rate /
765 360.0f; // 122.5 hz (at 44100); 61 hz (at 22050)
766 return true;
767 }
768
769 bool begin(AudioInfo info, float frequency) {
770 SoundGenerator<T>::begin(info);
771 base_frequency = SoundGenerator<T>::audioInfo().sample_rate /
772 360.0f; // 122.5 hz (at 44100); 61 hz (at 22050)
773 setFrequency(frequency);
774 return true;
775 }
776
777 bool begin(int channels, int sample_rate, uint16_t frequency = 0) {
778 SoundGenerator<T>::info.channels = channels;
779 SoundGenerator<T>::info.sample_rate = sample_rate;
780 return begin(SoundGenerator<T>::info, frequency);
781 }
782
783 void setFrequency(float freq) {
784 step_new = freq / base_frequency;
785 if (is_first) {
786 step = step_new;
787 is_first = false;
788 }
789 LOGD("step: %f", step_new);
790 }
791
792 protected:
793 bool is_first = true;
794 float amplitude;
795 float amplitude_to_be;
796 float max_amplitude_step = 50.0f;
797 float base_frequency = 1.0f;
798 float step = 1.0f;
799 float step_new = 1.0f;
800 float angle = 0.0f;
801 // 122.5 hz (at 44100); 61 hz (at 22050)
802 const float values[181] = {
803 0, 0.0174524, 0.0348995, 0.052336, 0.0697565, 0.0871557,
804 0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809,
805 0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372,
806 0.309017, 0.325568, 0.34202, 0.358368, 0.374607, 0.390731,
807 0.406737, 0.422618, 0.438371, 0.45399, 0.469472, 0.48481,
808 0.5, 0.515038, 0.529919, 0.544639, 0.559193, 0.573576,
809 0.587785, 0.601815, 0.615661, 0.62932, 0.642788, 0.656059,
810 0.669131, 0.681998, 0.694658, 0.707107, 0.71934, 0.731354,
811 0.743145, 0.75471, 0.766044, 0.777146, 0.788011, 0.798636,
812 0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167,
813 0.866025, 0.87462, 0.882948, 0.891007, 0.898794, 0.906308,
814 0.913545, 0.920505, 0.927184, 0.93358, 0.939693, 0.945519,
815 0.951057, 0.956305, 0.961262, 0.965926, 0.970296, 0.97437,
816 0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546,
817 0.994522, 0.996195, 0.997564, 0.99863, 0.999391, 0.999848,
818 1, 0.999848, 0.999391, 0.99863, 0.997564, 0.996195,
819 0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627,
820 0.978148, 0.97437, 0.970296, 0.965926, 0.961262, 0.956305,
821 0.951057, 0.945519, 0.939693, 0.93358, 0.927184, 0.920505,
822 0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.87462,
823 0.866025, 0.857167, 0.848048, 0.838671, 0.829038, 0.819152,
824 0.809017, 0.798636, 0.788011, 0.777146, 0.766044, 0.75471,
825 0.743145, 0.731354, 0.71934, 0.707107, 0.694658, 0.681998,
826 0.669131, 0.656059, 0.642788, 0.62932, 0.615661, 0.601815,
827 0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038,
828 0.5, 0.48481, 0.469472, 0.45399, 0.438371, 0.422618,
829 0.406737, 0.390731, 0.374607, 0.358368, 0.34202, 0.325568,
830 0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951,
831 0.207912, 0.190809, 0.173648, 0.156434, 0.139173, 0.121869,
832 0.104528, 0.0871557, 0.0697565, 0.052336, 0.0348995, 0.0174524,
833 0};
834
835 T interpolate(float angle) {
836 bool positive = (angle <= 180.0f);
837 float angle_positive = positive ? angle : angle - 180.0f;
838 int angle_int1 = angle_positive;
839 int angle_int2 = angle_int1 + 1;
840 T v1 = values[angle_int1] * amplitude;
841 T v2 = values[angle_int2] * amplitude;
842 T result = v1 < v2 ? map(angle_positive, angle_int1, angle_int2, v1, v2)
843 : map(angle_positive, angle_int1, angle_int2, v2, v1);
844 // float result = v1;
845 return positive ? result : -result;
846 }
847
848 T map(T x, T in_min, T in_max, T out_min, T out_max) {
849 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
850 }
851
852 void updateAmplitudeInSteps() {
853 float diff = amplitude_to_be - amplitude;
854 if (abs(diff) > max_amplitude_step) {
855 diff = (diff < 0) ? -max_amplitude_step : max_amplitude_step;
856 }
857 if (abs(diff) >= 1.0f) {
858 amplitude += diff;
859 }
860 }
861};
862
871template <class T = int16_t>
873 public:
874 GeneratorMixer() = default;
875
876 void add(SoundGenerator<T>& generator) { vector.push_back(&generator); }
877 void add(SoundGenerator<T>* generator) { vector.push_back(generator); }
878
879 void clear() { vector.clear(); }
880
882 float total = 0.0f;
883 float count = 0.0f;
884 for (auto& generator : vector) {
885 if (generator->isActive()) {
886 T sample = generator->readSample();
887 total += sample;
888 count += 1.0f;
889 }
890 }
891 return count > 0.0f ? total / count : 0;
892 }
893
894 protected:
896 int actualChannel = 0;
897};
898
907template <class T = int16_t>
908class TestGenerator : public SoundGenerator<T> {
909 public:
910 TestGenerator(T max = 1000, T inc = 1) { this->max = max; }
911
912 T readSample() override {
913 value += inc;
914 if (abs(value) >= max) {
915 inc = -inc;
916 value += (inc * 2);
917 }
918 return value;
919 }
920
921 protected:
922 T max;
923 T value = 0;
924 T inc = 1;
925};
926
927} // namespace audio_tools
virtual int readArray(T data[], int len)
reads multiple values
Definition Buffers.h:33
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition Buffers.h:55
Sine wave which is based on a fast approximation function.
Definition SoundGenerator.h:320
float sine(float t)
sine approximation.
Definition SoundGenerator.h:341
virtual T readSample() override
Provides a single sample.
Definition SoundGenerator.h:327
Just returns a constant value.
Definition SoundGenerator.h:694
T readSample() override
Provides a single sample.
Definition SoundGenerator.h:712
bool begin() override
Starts the generation of samples.
Definition SoundGenerator.h:703
We generate the samples from an array which is provided in the constructor.
Definition SoundGenerator.h:573
void end() override
ends the processing
Definition SoundGenerator.h:626
GeneratorFromArray(T(&array)[arrayLen], int repeat=0, bool setInactiveAtEnd=false, size_t startIndex=0)
Construct a new Generator from an array.
Definition SoundGenerator.h:589
T readSample() override
Provides a single sample.
Definition SoundGenerator.h:629
bool begin() override
Starts the generation of samples.
Definition SoundGenerator.h:617
An Adapter Class which lets you use any Stream as a Generator.
Definition SoundGenerator.h:509
void setStream(Stream &input)
(Re-)Assigns a stream to the Adapter class
Definition SoundGenerator.h:532
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:524
T readSample()
Provides a single sample from the stream.
Definition SoundGenerator.h:537
Generator which combines (mixes) multiple sound generators into one output.
Definition SoundGenerator.h:872
T readSample()
Provides a single sample.
Definition SoundGenerator.h:881
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition AudioTypes.h:301
Generates pink noise.
Definition SoundGenerator.h:440
PinkNoiseGenerator(T amplitude=32767)
the amplitude defines the max value which is generated
Definition SoundGenerator.h:443
T readSample()
Provides a single sample.
Definition SoundGenerator.h:451
virtual bool resize(int len)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:418
SawToothGenerator.
Definition SoundGenerator.h:383
virtual T readSample() override
Provides a single sample.
Definition SoundGenerator.h:390
float saw(float t)
sine approximation.
Definition SoundGenerator.h:404
Provides a fixed value (e.g. 0) as sound data. This can be used e.g. to test the output functionality...
Definition SoundGenerator.h:487
T readSample()
Provides a single sample.
Definition SoundGenerator.h:493
A sine generator based on a table. The table is created using degrees where one full wave is 360 degr...
Definition SoundGenerator.h:731
void setFrequency(float freq)
Abstract method: not implemented! Just provides an error message...
Definition SoundGenerator.h:783
void setAmplitude(float amplitude)
Defines the new amplitude (volume)
Definition SoundGenerator.h:739
void setMaxAmplitudeStep(float step)
Definition SoundGenerator.h:743
T readSample()
Provides a single sample.
Definition SoundGenerator.h:745
Generates a Sound with the help of sin() function. If you plan to change the amplitude or frequency (...
Definition SoundGenerator.h:220
void setFrequency(float frequency) override
Defines the frequency - after the processing has been started.
Definition SoundGenerator.h:274
virtual T readSample() override
Provides a single sample.
Definition SoundGenerator.h:285
virtual void setAudioInfo(AudioInfo info) override
Defines/updates the AudioInfo.
Definition SoundGenerator.h:264
virtual AudioInfo defaultConfig() override
Provides the default configuration.
Definition SoundGenerator.h:269
Base class to define the abstract interface for the sound generating classes.
Definition SoundGenerator.h:28
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:62
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:56
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:52
virtual AudioInfo defaultConfig()
Provides the default configuration.
Definition SoundGenerator.h:75
Generates a square wave sound.
Definition SoundGenerator.h:356
virtual T readSample()
Provides a single sample.
Definition SoundGenerator.h:363
Definition NoArduino.h:142
Generates a test signal which is easy to check because the values are incremented or decremented by 1...
Definition SoundGenerator.h:908
T readSample() override
Provides a single sample.
Definition SoundGenerator.h:912
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:191
virtual float volume()
provides the actual volume in the range of 0.0f to 1.0f
Definition AudioTypes.h:194
virtual bool setVolume(float volume)
define the actual volume in the range of 0.0f to 1.0f
Definition AudioTypes.h:196
Generates a random noise sound with the help of rand() function.
Definition SoundGenerator.h:418
WhiteNoiseGenerator(T amplitude=32767)
the scale defines the max value which is generated
Definition SoundGenerator.h:421
T readSample()
Provides a single sample.
Definition SoundGenerator.h:424
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:55
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:57
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:59
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:61