arduino-audio-tools
Loading...
Searching...
No Matches
SoundGenerator.h
Go to the documentation of this file.
1#pragma once
2
3#include <math.h>
4
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
35 virtual bool begin(AudioInfo info) {
36 this->info = info;
37 return begin();
38 }
39
41 virtual bool begin() {
42 TRACED();
43 active = true;
44 activeWarningIssued = false;
45 info.logInfo("SoundGenerator:");
46
47 // support bytes < framesize
48 ring_buffer.resize(info.channels * sizeof(T));
49
50 return true;
51 }
52
54 virtual void end() { active = false; }
55
57 virtual bool isActive() { return active; }
58
60 virtual T readSample() = 0;
61
63 virtual size_t readBytes(uint8_t* data, size_t len) {
64 LOGD("readBytes: %d", (int)len);
65 if (!active) return 0;
66 int channels = audioInfo().channels;
67 int frame_size = sizeof(T) * channels;
68 int frames = len / frame_size;
69 if (len >= frame_size) {
70 return readBytesFrames(data, len, frames, channels);
71 }
72 return readBytesFromBuffer(data, len, frame_size, channels);
73 }
74
78 def.bits_per_sample = sizeof(T) * 8;
79 return def;
80 }
81
83 virtual void setFrequency(float frequency) {
84 LOGE("setFrequency not supported");
85 }
86
88 virtual AudioInfo audioInfo() { return info; }
89
91 virtual void setAudioInfo(AudioInfo info) {
92 this->info = info;
93 if (info.bits_per_sample != sizeof(T) * 8) {
94 LOGE("invalid bits_per_sample: %d", info.channels);
95 }
97 }
98
101 uint8_t downPercent = 30) {
102 LOGI("setPlayTime: playMs=%d, upPercent=%d, downPercent=%d", playMs,
104 this->playMs = playMs;
105 this->upPercent = upPercent;
106 this->downPercent = downPercent;
107 currentSample = 0;
109 factor = 0.0f;
110 }
111
112 protected:
113 bool active = false;
115 // int output_channels = 1;
124 float rampUpInc = 0.0;
125 float rampDownDec = 0.0;
126 float factor = 1.0f;
128
130 if (upPercent + downPercent > 100) {
131 downPercent = 100 - upPercent;
132 }
134 upSamples = (playSamples * upPercent) / 100;
136 rampUpInc = 0;
137 if (upSamples > 0) {
138 rampUpInc = 1.0f / upSamples;
139 }
140 rampDownDec = 0;
141 if (rampDownSamples > 0) {
143 }
144 }
145
146 size_t readBytesFrames(uint8_t* buffer, size_t lengthBytes, int frames,
147 int channels) {
148 T* result_buffer = (T*)buffer;
149 int frames_written = 0;
150 if (playMs > 0 && currentSample > playSamples) {
151 return 0;
152 }
153
154 for (int j = 0; j < frames; j++) {
155 T sample = readSample();
156
157 // if we requested a play time
158 if (playMs > 0) {
160 sample = applyRamp(sample);
161 }
162
163 for (int ch = 0; ch < channels; ch++) {
164 *result_buffer++ = sample;
165 }
166
168 // exit loop if we have reached the requested play time
169 if (playMs > 0 && currentSample > playSamples) {
170 break;
171 }
172 }
173 return frames_written * sizeof(T) * channels;
174 }
175
176 // Applies ramp up and ramp down logic to the sample
177 T applyRamp(T sample) {
178 // Ramp up
179 if (rampUpInc > 0 && currentSample <= upSamples) {
180 factor += rampUpInc;
181 if (factor > 1.0f) {
182 factor = 1.0f;
183 }
184 }
185 // Ramp down
188 if (factor < 0.0f) {
189 factor = 0.0f;
190 }
191 }
192 // Sustain
193 else {
194 factor = 1.0f;
195 }
196 return (T)(factor * sample);
197 }
198
200 int frame_size, int channels) {
201 // fill ringbuffer with one frame
202 if (ring_buffer.isEmpty()) {
203 uint8_t tmp[frame_size];
204 readBytesFrames(tmp, frame_size, 1, channels);
205 ring_buffer.writeArray(tmp, frame_size);
206 }
207 // provide result
208 return ring_buffer.readArray(buffer, lengthBytes);
209 }
210};
211
221template <class T = int16_t>
222class SineGenerator : public SoundGenerator<T> {
223 public:
224 // the scale defines the max value which is generated
225 SineGenerator(float amplitude = 0.9f * NumberConverter::maxValueT<T>(),
226 float phase = 0.0f) {
227 LOGD("SineGenerator");
228 m_amplitude = amplitude;
229 m_phase = phase;
230 }
231
232 bool begin() override {
233 TRACEI();
235 this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
236 return true;
237 }
238
239 bool begin(AudioInfo info) override {
240 LOGI("%s::begin(channels=%d, sample_rate=%d)", "SineGenerator",
241 (int)info.channels, (int)info.sample_rate);
243 this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
244 return true;
245 }
246
247 bool begin(AudioInfo info, float frequency) {
248 LOGI("%s::begin(channels=%d, sample_rate=%d, frequency=%.2f)",
249 "SineGenerator", (int)info.channels, (int)info.sample_rate,
250 frequency);
252 this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
253 if (frequency > 0.0f) {
254 setFrequency(frequency);
255 }
256 return true;
257 }
258
259 bool begin(int channels, int sample_rate, float frequency) {
260 SoundGenerator<T>::info.channels = channels;
261 SoundGenerator<T>::info.sample_rate = sample_rate;
262 return begin(SoundGenerator<T>::info, frequency);
263 }
264
265 // update m_deltaTime
266 virtual void setAudioInfo(AudioInfo info) override {
268 this->m_deltaTime = 1.0f / SoundGenerator<T>::info.sample_rate;
269 }
270
271 virtual AudioInfo defaultConfig() override {
273 }
274
276 void setFrequency(float frequency) override {
277 LOGI("setFrequency: %.2f", frequency);
278 LOGI("active: %s", SoundGenerator<T>::active ? "true" : "false");
279 if (m_frequency != frequency) {
280 m_cycles = 0.0f; // reset cycles to avoid phase jumps
281 m_phase = 0.0f; // reset phase to avoid jumps
282 }
283 m_frequency = frequency;
284 }
285
287 virtual T readSample() override {
288 float angle = double_Pi * m_cycles + m_phase;
289 T result = m_amplitude * sinf(angle);
291 if (m_cycles > 1.0f) {
292 m_cycles -= 1.0f;
293 }
294 return result;
295 }
296
297 void setAmplitude(float amp) { m_amplitude = amp; }
298
299 protected:
300 volatile float m_frequency = 0.0f;
301 float m_cycles = 0.0f; // Varies between 0.0 and 1.0
302 float m_amplitude = 1.0f;
303 float m_deltaTime = 0.0f;
304 float m_phase = 0.0f;
305 const float double_Pi = 2.0f * PI;
306
307 void logStatus() {
308 SoundGenerator<T>::info.logStatus();
309 LOGI("amplitude: %f", this->m_amplitude);
310 LOGI("active: %s", SoundGenerator<T>::active ? "true" : "false");
311 }
312};
313
315template <class T = int16_t>
317
325template <class T = int16_t>
327 public:
328 FastSineGenerator(float amplitude = 32767.0, float phase = 0.0)
329 : SineGenerator<T>(amplitude, phase) {
330 LOGD("FastSineGenerator");
331 }
332
333 virtual T readSample() override {
334 float angle =
336 T result = SineGenerator<T>::m_amplitude * sine(angle);
339 if (SineGenerator<T>::m_cycles > 1.0f) {
341 }
342 return result;
343 }
344
345 protected:
347 inline float sine(float t) {
348 float p = (t - (int)t) - 0.5f; // 0 <= p <= 1
349 float pp = p * p;
350 return (p - 6.283211f * pp * p + 9.132843f * pp * pp * p) * -6.221086f;
351 }
352};
353
361template <class T = int16_t>
363 public:
364 SquareWaveGenerator(float amplitude = 32767.0f, float phase = 0.0f)
365 : FastSineGenerator<T>(amplitude, phase) {
366 LOGD("SquareWaveGenerator");
367 }
368
373
374 protected:
375 // returns amplitude for positive vales and -amplitude for negative values
376 T value(T value, T amplitude) {
377 return (value >= 0) ? amplitude : -amplitude;
378 }
379};
380
388template <class T = int16_t>
390 public:
391 SawToothGenerator(float amplitude = 32767.0, float phase = 0.0)
392 : SineGenerator<T>(amplitude, phase) {
393 LOGD("SawToothGenerator");
394 }
395
407
408 protected:
410 inline float saw(float t) {
411 float p = (t - (int)t) - 0.5f; // 0 <= p <= 1
412 return p;
413 }
414};
415
423template <class T = int16_t>
425 public:
428
431
432 protected:
434 // //range : [min, max]
435 int random(int min, int max) { return min + rand() % ((max + 1) - min); }
436};
437
445template <class T = int16_t>
447 public:
450 this->amplitude = amplitude;
451 max_key = 0x1f; // Five bits set
452 key = 0;
453 for (int i = 0; i < 5; i++) white_values[i] = rand() % (amplitude / 5);
454 }
455
458 T last_key = key;
459 unsigned int sum;
460
461 key++;
462 if (key > max_key) key = 0;
463 // Exclusive-Or previous value with current value. This gives
464 // a list of bits that have changed.
465 int diff = last_key ^ key;
466 sum = 0;
467 for (int i = 0; i < 5; i++) {
468 // If bit changed get new random number for corresponding
469 // white_value
470 if (diff & (1 << i)) white_values[i] = rand() % (amplitude / 5);
471 sum += white_values[i];
472 }
473 return sum;
474 }
475
476 protected:
479 unsigned int white_values[5];
480 unsigned int amplitude;
481};
482
492template <class T = int16_t>
494 public:
495 // the scale defines the max value which is generated
497
500 return value; // return 0
501 }
502
503 protected:
505};
506
514template <class T = int16_t>
516 public:
520
530 GeneratorFromStream(Stream& input, int channels = 1, float volume = 1.0) {
531 maxValue = NumberConverter::maxValue(sizeof(T) * 8);
532 setStream(input);
535 }
536
538 void setStream(Stream& input) { this->p_stream = &input; }
539
540 void setChannels(int channels) { this->channels = channels; }
541
544 T data = 0;
545 float total = 0;
546 if (p_stream != nullptr) {
547 for (int j = 0; j < channels; j++) {
548 p_stream->readBytes((uint8_t*)&data, sizeof(T));
549 total += data;
550 }
551 float avg = (total / channels) * volume();
552 if (avg > maxValue) {
553 data = maxValue;
554 } else if (avg < -maxValue) {
555 data = -maxValue;
556 } else {
557 data = avg;
558 }
559 }
560 return data;
561 }
562
563 protected:
564 Stream* p_stream = nullptr;
565 int channels = 1;
566 float maxValue;
567};
568
578template <class T = int16_t>
580 public:
594 template <size_t arrayLen>
596 bool setInactiveAtEnd = false, size_t startIndex = 0) {
597 TRACED();
598 this->max_repeat = repeat;
600 this->sound_index = startIndex;
601 setArray(array, arrayLen);
602 }
603
604 template <int arrayLen>
605 void setArray(T (&array)[arrayLen]) {
606 TRACED();
607 setArray(array, arrayLen);
608 }
609
610 void setArray(T* array, size_t size) {
611 table.resize(size);
612 for (int j = 0; j < size; j++) {
613 table[j] = array[j];
614 }
615 LOGI("table_length: %d", (int)size);
616 }
617
619 bool begin(AudioInfo info) override {
621 }
622
625 bool rc = begin(info);
627 return rc;
628 }
629
631 bool begin() override {
632 TRACEI();
634 sound_index = 0.0f;
635 repeat_counter = 0;
636 is_running = true;
637 return true;
638 }
639
640 void end() override { table.resize(0); }
641
643 T readSample() override {
644 if (table.size() == 0) {
645 return 0;
646 }
647
648 if (!this->is_running) {
649 return 0;
650 }
651
652 const float table_size = static_cast<float>(table.size());
653
654 // at end deactivate output
655 while (sound_index >= table_size) {
656 // LOGD("reset index - sound_index: %d, table_length:
657 // %d",sound_index,table_length);
659 // deactivate when count has been used up
660 if (max_repeat >= 1 && ++repeat_counter >= max_repeat) {
661 LOGD("atEnd");
662 this->is_running = false;
663 if (inactive_at_end) {
664 this->active = false;
665 }
666 return 0;
667 }
668 }
669
670 // LOGD("index: %d - active: %d", sound_index, this->active);
671 T result = 0;
672 if (this->is_running) {
673 int idx0 = static_cast<int>(sound_index);
674 int idx1 = idx0 + 1;
675 if (idx1 >= static_cast<int>(table.size())) {
676 idx1 = 0;
677 }
678 float frac = sound_index - static_cast<float>(idx0);
679 float sample = static_cast<float>(table[idx0]) * (1.0f - frac) +
680 static_cast<float>(table[idx1]) * frac;
681 result = static_cast<T>(sample);
683 }
684
685 return result;
686 }
687
688 // step size the sound index is incremented (default = 1)
689 void setIncrement(int inc) {
690 index_increment = inc;
691 frequency = 0.0f;
692 }
693
695 void setFrequency(float frequency) override {
696 if (SoundGenerator<T>::audioInfo().sample_rate <= 0 || table.size() == 0) {
697 LOGE("setFrequency failed: sample_rate=%d table_size=%d",
698 (int)SoundGenerator<T>::audioInfo().sample_rate, (int)table.size());
699 return;
700 }
701 if (frequency < 0.0f) {
702 frequency = 0.0f;
703 }
704 this->frequency = frequency;
706 frequency * static_cast<float>(table.size()) /
707 static_cast<float>(SoundGenerator<T>::audioInfo().sample_rate);
708 }
709
710 // Sets up a sine table - returns the effective frequency
711 int setupSine(int sampleRate, float reqFrequency, float amplitude = 1.0) {
712 int sample_count =
713 static_cast<float>(sampleRate) /
714 reqFrequency; // e.g. 44100 / 300hz = 147 samples per wave
715 float angle = 2.0 * PI / sample_count;
716 table.resize(sample_count);
717 for (int j = 0; j < sample_count; j++) {
718 table[j] = sinf(j * angle) * amplitude;
719 }
720 // calculate effective frequency
721 return sampleRate / sample_count;
722 }
723
724 // Similar like is active to check if the array is still playing.
725 bool isRunning() { return is_running; }
726
727 protected:
728 float sound_index = 0.0f;
729 int max_repeat = 0;
731 bool inactive_at_end = false;
732 bool is_running = false;
733 bool owns_data = false;
735 float index_increment = 1.0f;
736 float frequency = 0.0f;
737};
738
746template <class T = int16_t>
748 public:
750
752
753 void setValue(T value) { value_set = value; }
754
756 bool begin() override {
757 TRACEI();
759 is_running = true;
761 return true;
762 }
763
765 T readSample() override { return value_return; }
766
767 // Similar like is active to check if the array is still playing.
768 bool isRunning() { return is_running; }
769
770 protected:
773 bool is_running = false;
774};
775
783template <class T = int16_t>
784class SineFromTable : public SoundGenerator<T> {
785 public:
786 SineFromTable(float amplitude = 32767.0) {
787 this->amplitude = amplitude;
789 }
790
793
797
799 // update angle
800 angle += step;
801 if (angle >= 360.0f) {
802 while (angle >= 360.0f) {
803 angle -= 360.0f;
804 }
805 // update frequency at start of circle (near 0 degrees)
806 step = step_new;
807
809 // amplitude = amplitude_to_be;
810 }
811 return interpolate(angle);
812 }
813
814 bool begin() {
815 is_first = true;
818 360.0f; // 122.5 hz (at 44100); 61 hz (at 22050)
819 return true;
820 }
821
822 bool begin(AudioInfo info, float frequency) {
825 360.0f; // 122.5 hz (at 44100); 61 hz (at 22050)
826 setFrequency(frequency);
827 return true;
828 }
829
830 bool begin(int channels, int sample_rate, uint16_t frequency = 0) {
831 SoundGenerator<T>::info.channels = channels;
832 SoundGenerator<T>::info.sample_rate = sample_rate;
833 return begin(SoundGenerator<T>::info, frequency);
834 }
835
836 void setFrequency(float freq) {
837 step_new = freq / base_frequency;
838 if (is_first) {
839 step = step_new;
840 is_first = false;
841 }
842 LOGD("step: %f", step_new);
843 }
844
845 protected:
846 bool is_first = true;
849 float max_amplitude_step = 50.0f;
850 float base_frequency = 1.0f;
851 float step = 1.0f;
852 float step_new = 1.0f;
853 float angle = 0.0f;
854 // 122.5 hz (at 44100); 61 hz (at 22050)
855 const float values[181] = {
856 0, 0.0174524, 0.0348995, 0.052336, 0.0697565, 0.0871557,
857 0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809,
858 0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372,
859 0.309017, 0.325568, 0.34202, 0.358368, 0.374607, 0.390731,
860 0.406737, 0.422618, 0.438371, 0.45399, 0.469472, 0.48481,
861 0.5, 0.515038, 0.529919, 0.544639, 0.559193, 0.573576,
862 0.587785, 0.601815, 0.615661, 0.62932, 0.642788, 0.656059,
863 0.669131, 0.681998, 0.694658, 0.707107, 0.71934, 0.731354,
864 0.743145, 0.75471, 0.766044, 0.777146, 0.788011, 0.798636,
865 0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167,
866 0.866025, 0.87462, 0.882948, 0.891007, 0.898794, 0.906308,
867 0.913545, 0.920505, 0.927184, 0.93358, 0.939693, 0.945519,
868 0.951057, 0.956305, 0.961262, 0.965926, 0.970296, 0.97437,
869 0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546,
870 0.994522, 0.996195, 0.997564, 0.99863, 0.999391, 0.999848,
871 1, 0.999848, 0.999391, 0.99863, 0.997564, 0.996195,
872 0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627,
873 0.978148, 0.97437, 0.970296, 0.965926, 0.961262, 0.956305,
874 0.951057, 0.945519, 0.939693, 0.93358, 0.927184, 0.920505,
875 0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.87462,
876 0.866025, 0.857167, 0.848048, 0.838671, 0.829038, 0.819152,
877 0.809017, 0.798636, 0.788011, 0.777146, 0.766044, 0.75471,
878 0.743145, 0.731354, 0.71934, 0.707107, 0.694658, 0.681998,
879 0.669131, 0.656059, 0.642788, 0.62932, 0.615661, 0.601815,
880 0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038,
881 0.5, 0.48481, 0.469472, 0.45399, 0.438371, 0.422618,
882 0.406737, 0.390731, 0.374607, 0.358368, 0.34202, 0.325568,
883 0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951,
884 0.207912, 0.190809, 0.173648, 0.156434, 0.139173, 0.121869,
885 0.104528, 0.0871557, 0.0697565, 0.052336, 0.0348995, 0.0174524,
886 0};
887
889 bool positive = (angle <= 180.0f);
890 float angle_positive = positive ? angle : angle - 180.0f;
892 int angle_int2 = angle_int1 + 1;
895 T result = v1 < v2 ? map(angle_positive, angle_int1, angle_int2, v1, v2)
897 // float result = v1;
898 return positive ? result : -result;
899 }
900
902 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
903 }
904
907 if (abs(diff) > max_amplitude_step) {
909 }
910 if (abs(diff) >= 1.0f) {
911 amplitude += diff;
912 }
913 }
914};
915
924template <class T = int16_t>
926 public:
927 GeneratorMixer() = default;
928
929 void add(SoundGenerator<T>& generator) { vector.push_back(&generator); }
930 void add(SoundGenerator<T>* generator) { vector.push_back(generator); }
931
932 void clear() { vector.clear(); }
933
935 float total = 0.0f;
936 float count = 0.0f;
937 for (auto& generator : vector) {
938 if (generator->isActive()) {
939 T sample = generator->readSample();
940 total += sample;
941 count += 1.0f;
942 }
943 }
944 return count > 0.0f ? total / count : 0;
945 }
946
947 protected:
950};
951
960template <class T = int16_t>
961class TestGenerator : public SoundGenerator<T> {
962 public:
963 TestGenerator(T max = 1000, T inc = 1) { this->max = max; }
964
965 T readSample() override {
966 value += inc;
967 if (abs(value) >= max) {
968 inc = -inc;
969 value += (inc * 2);
970 }
971 return value;
972 }
973
974 protected:
976 T value = 0;
977 T inc = 1;
978};
979
980} // namespace audio_tools
#define PI
Definition AudioEffectsSuite.h:27
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
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:326
float sine(float t)
sine approximation.
Definition SoundGenerator.h:347
virtual T readSample() override
Provides a single sample.
Definition SoundGenerator.h:333
FastSineGenerator(float amplitude=32767.0, float phase=0.0)
Definition SoundGenerator.h:328
Just returns a constant value.
Definition SoundGenerator.h:747
T value_set
Definition SoundGenerator.h:771
bool isRunning()
Definition SoundGenerator.h:768
virtual bool begin(AudioInfo info)
Starts the processing with the provided AudioInfo.
Definition SoundGenerator.h:751
T readSample() override
Provides a single sample.
Definition SoundGenerator.h:765
bool is_running
Definition SoundGenerator.h:773
bool begin() override
Starts the generation of samples.
Definition SoundGenerator.h:756
T value_return
Definition SoundGenerator.h:772
void setValue(T value)
Definition SoundGenerator.h:753
We generate the samples from an array which is provided in the constructor.
Definition SoundGenerator.h:579
void setFrequency(float frequency) override
Defines the output frequency based on sample rate and table size.
Definition SoundGenerator.h:695
void setIncrement(int inc)
Definition SoundGenerator.h:689
int setupSine(int sampleRate, float reqFrequency, float amplitude=1.0)
Definition SoundGenerator.h:711
bool isRunning()
Definition SoundGenerator.h:725
bool inactive_at_end
Definition SoundGenerator.h:731
Vector< T > table
Definition SoundGenerator.h:734
void end() override
Ends the processing.
Definition SoundGenerator.h:640
float sound_index
Definition SoundGenerator.h:728
void setArray(T *array, size_t size)
Definition SoundGenerator.h:610
float index_increment
Definition SoundGenerator.h:735
GeneratorFromArray(T(&array)[arrayLen], int repeat=0, bool setInactiveAtEnd=false, size_t startIndex=0)
Construct a new Generator from an array.
Definition SoundGenerator.h:595
T readSample() override
Provides a single sample.
Definition SoundGenerator.h:643
bool is_running
Definition SoundGenerator.h:732
int max_repeat
Definition SoundGenerator.h:729
bool owns_data
Definition SoundGenerator.h:733
int repeat_counter
Definition SoundGenerator.h:730
bool begin(AudioInfo info) override
Starts the generation of samples with the provided AudioInfo.
Definition SoundGenerator.h:619
bool begin() override
Starts the generation of samples.
Definition SoundGenerator.h:631
float frequency
Definition SoundGenerator.h:736
bool begin(AudioInfo info, float frequency)
Starts the generation of samples with the provided AudioInfo and frequency.
Definition SoundGenerator.h:624
void setArray(T(&array)[arrayLen])
Definition SoundGenerator.h:605
An Adapter Class which lets you use any Stream as a Generator.
Definition SoundGenerator.h:515
int channels
Definition SoundGenerator.h:565
GeneratorFromStream()
Definition SoundGenerator.h:517
Stream * p_stream
Definition SoundGenerator.h:564
void setStream(Stream &input)
(Re-)Assigns a stream to the Adapter class
Definition SoundGenerator.h:538
void setChannels(int channels)
Definition SoundGenerator.h:540
float maxValue
Definition SoundGenerator.h:566
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:530
T readSample()
Provides a single sample from the stream.
Definition SoundGenerator.h:543
Generator which combines (mixes) multiple sound generators into one output.
Definition SoundGenerator.h:925
void add(SoundGenerator< T > *generator)
Definition SoundGenerator.h:930
Vector< SoundGenerator< T > * > vector
Definition SoundGenerator.h:948
int actualChannel
Definition SoundGenerator.h:949
void clear()
Definition SoundGenerator.h:932
T readSample()
Provides a single sample.
Definition SoundGenerator.h:934
void add(SoundGenerator< T > &generator)
Definition SoundGenerator.h:929
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:446
PinkNoiseGenerator(T amplitude=32767)
the amplitude defines the max value which is generated
Definition SoundGenerator.h:449
T key
Definition SoundGenerator.h:478
unsigned int amplitude
Definition SoundGenerator.h:480
T max_key
Definition SoundGenerator.h:477
unsigned int white_values[5]
Definition SoundGenerator.h:479
T readSample()
Provides a single sample.
Definition SoundGenerator.h:457
Implements a typed Ringbuffer.
Definition Buffers.h:341
bool isEmpty()
Definition Buffers.h:388
virtual bool resize(int len)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:418
SawToothGenerator.
Definition SoundGenerator.h:389
virtual T readSample() override
Provides a single sample.
Definition SoundGenerator.h:396
SawToothGenerator(float amplitude=32767.0, float phase=0.0)
Definition SoundGenerator.h:391
float saw(float t)
sine approximation.
Definition SoundGenerator.h:410
Provides a fixed value (e.g. 0) as sound data. This can be used e.g. to test the output functionality...
Definition SoundGenerator.h:493
SilenceGenerator(T value=0)
Definition SoundGenerator.h:496
T value
Definition SoundGenerator.h:504
T readSample()
Provides a single sample.
Definition SoundGenerator.h:499
A sine generator based on a table. The table is created using degrees where one full wave is 360 degr...
Definition SoundGenerator.h:784
float amplitude
Definition SoundGenerator.h:847
T interpolate(float angle)
Definition SoundGenerator.h:888
float base_frequency
Definition SoundGenerator.h:850
const float values[181]
Definition SoundGenerator.h:855
T map(T x, T in_min, T in_max, T out_min, T out_max)
Definition SoundGenerator.h:901
void updateAmplitudeInSteps()
Definition SoundGenerator.h:905
bool is_first
Definition SoundGenerator.h:846
float step_new
Definition SoundGenerator.h:852
bool begin()
Starts the processing.
Definition SoundGenerator.h:814
bool begin(int channels, int sample_rate, uint16_t frequency=0)
Definition SoundGenerator.h:830
void setFrequency(float freq)
Abstract method: not implemented! Just provides an error message...
Definition SoundGenerator.h:836
float step
Definition SoundGenerator.h:851
float amplitude_to_be
Definition SoundGenerator.h:848
SineFromTable(float amplitude=32767.0)
Definition SoundGenerator.h:786
float angle
Definition SoundGenerator.h:853
float max_amplitude_step
Definition SoundGenerator.h:849
void setAmplitude(float amplitude)
Defines the new amplitude (volume)
Definition SoundGenerator.h:792
void setMaxAmplitudeStep(float step)
Definition SoundGenerator.h:796
bool begin(AudioInfo info, float frequency)
Definition SoundGenerator.h:822
T readSample()
Provides a single sample.
Definition SoundGenerator.h:798
Generates a Sound with the help of sin() function. If performance is of concern, I suggest to use the...
Definition SoundGenerator.h:222
void setFrequency(float frequency) override
Defines the frequency - after the processing has been started.
Definition SoundGenerator.h:276
float m_phase
Definition SoundGenerator.h:304
SineGenerator(float amplitude=0.9f *NumberConverter::maxValueT< T >(), float phase=0.0f)
Definition SoundGenerator.h:225
void setAmplitude(float amp)
Definition SoundGenerator.h:297
virtual T readSample() override
Provides a single sample.
Definition SoundGenerator.h:287
volatile float m_frequency
Definition SoundGenerator.h:300
float m_deltaTime
Definition SoundGenerator.h:303
const float double_Pi
Definition SoundGenerator.h:305
bool begin(int channels, int sample_rate, float frequency)
Definition SoundGenerator.h:259
virtual void setAudioInfo(AudioInfo info) override
Defines/updates the AudioInfo.
Definition SoundGenerator.h:266
virtual AudioInfo defaultConfig() override
Provides the default configuration.
Definition SoundGenerator.h:271
bool begin(AudioInfo info) override
Starts the processing with the provided AudioInfo.
Definition SoundGenerator.h:239
bool begin() override
Starts the processing.
Definition SoundGenerator.h:232
bool begin(AudioInfo info, float frequency)
Definition SoundGenerator.h:247
void logStatus()
Definition SoundGenerator.h:307
float m_cycles
Definition SoundGenerator.h:301
float m_amplitude
Definition SoundGenerator.h:302
Base class to define the abstract interface for the sound generating classes.
Definition SoundGenerator.h:28
uint32_t rampDownSamples
Definition SoundGenerator.h:123
bool active
Definition SoundGenerator.h:113
void setPlayTime(uint32_t playMs, uint8_t upPercent=20, uint8_t downPercent=30)
Defines the play time in ms and the ramp up and ramp down time in percent.
Definition SoundGenerator.h:100
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:63
virtual T readSample()=0
Provides a single sample.
bool activeWarningIssued
Definition SoundGenerator.h:114
float factor
Definition SoundGenerator.h:126
uint32_t playMs
Definition SoundGenerator.h:118
virtual bool begin(AudioInfo info)
Starts the processing with the provided AudioInfo.
Definition SoundGenerator.h:35
AudioInfo info
Definition SoundGenerator.h:116
float rampDownDec
Definition SoundGenerator.h:125
SoundGenerator()
Definition SoundGenerator.h:30
virtual void setFrequency(float frequency)
Abstract method: not implemented! Just provides an error message...
Definition SoundGenerator.h:83
virtual bool begin()
Starts the processing.
Definition SoundGenerator.h:41
virtual bool isActive()
Checks if the begin method has been called - after end() isActive is false.
Definition SoundGenerator.h:57
void recalculatePlayTime()
Definition SoundGenerator.h:129
virtual void setAudioInfo(AudioInfo info)
Defines/updates the AudioInfo.
Definition SoundGenerator.h:91
T applyRamp(T sample)
Definition SoundGenerator.h:177
float rampUpInc
Definition SoundGenerator.h:124
size_t readBytesFrames(uint8_t *buffer, size_t lengthBytes, int frames, int channels)
Definition SoundGenerator.h:146
uint32_t upSamples
Definition SoundGenerator.h:122
uint32_t playSamples
Definition SoundGenerator.h:121
virtual AudioInfo audioInfo()
Provides the AudioInfo.
Definition SoundGenerator.h:88
virtual void end()
Ends the processing.
Definition SoundGenerator.h:54
virtual ~SoundGenerator()
Definition SoundGenerator.h:32
uint8_t downPercent
Definition SoundGenerator.h:120
uint8_t upPercent
Definition SoundGenerator.h:119
size_t readBytesFromBuffer(uint8_t *buffer, size_t lengthBytes, int frame_size, int channels)
Definition SoundGenerator.h:199
virtual AudioInfo defaultConfig()
Provides the default configuration.
Definition SoundGenerator.h:76
RingBuffer< uint8_t > ring_buffer
Definition SoundGenerator.h:117
uint32_t currentSample
Definition SoundGenerator.h:127
Generates a square wave sound.
Definition SoundGenerator.h:362
SquareWaveGenerator(float amplitude=32767.0f, float phase=0.0f)
Definition SoundGenerator.h:364
virtual T readSample()
Provides a single sample.
Definition SoundGenerator.h:369
T value(T value, T amplitude)
Definition SoundGenerator.h:376
Definition NoArduino.h:142
virtual size_t readBytes(uint8_t *data, size_t len)
Definition NoArduino.h:147
Generates a test signal which is easy to check because the values are incremented or decremented by 1...
Definition SoundGenerator.h:961
T inc
Definition SoundGenerator.h:977
T value
Definition SoundGenerator.h:976
T max
Definition SoundGenerator.h:975
T readSample() override
Provides a single sample.
Definition SoundGenerator.h:965
TestGenerator(T max=1000, T inc=1)
Definition SoundGenerator.h:963
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:424
T amplitude
Definition SoundGenerator.h:433
WhiteNoiseGenerator(T amplitude=32767)
the scale defines the max value which is generated
Definition SoundGenerator.h:427
int random(int min, int max)
Definition SoundGenerator.h:435
T readSample()
Provides a single sample.
Definition SoundGenerator.h:430
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:512
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
virtual void logInfo(const char *source="")
Definition AudioTypes.h:125