3 #include "AudioTools/CoreAudio/AudioBasic/Collections.h"
4 #include "AudioTools/CoreAudio/AudioLogger.h"
5 #include "AudioTools/CoreAudio/AudioTypes.h"
38 virtual bool begin() {
41 activeWarningIssued =
false;
42 info.logInfo(
"SoundGenerator:");
45 ring_buffer.resize(info.
channels *
sizeof(T));
51 virtual void end() { active =
false; }
61 virtual size_t readBytes(uint8_t *data,
size_t len) {
62 LOGD(
"readBytes: %d", (
int)len);
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);
71 return readBytesFromBuffer(data, len, frame_size, channels);
83 LOGE(
"setFrequency not supported");
93 LOGE(
"invalid bits_per_sample: %d", info.
channels);
99 bool activeWarningIssued =
false;
104 size_t readBytesFrames(uint8_t *buffer,
size_t lengthBytes,
int frames,
106 T *result_buffer = (T *)buffer;
107 for (
int j = 0; j < frames; j++) {
109 for (
int ch = 0; ch < channels; ch++) {
110 *result_buffer++ = sample;
113 return frames *
sizeof(T) * channels;
116 size_t readBytesFromBuffer(uint8_t *buffer,
size_t lengthBytes,
117 int frame_size,
int channels) {
119 if (ring_buffer.isEmpty()) {
120 uint8_t tmp[frame_size];
121 readBytesFrames(tmp, frame_size, 1, channels);
125 return ring_buffer.
readArray(buffer, lengthBytes);
142 float phase = 0.0f) {
143 LOGD(
"SineWaveGenerator");
144 m_amplitude = amplitude;
148 bool begin()
override {
156 LOGI(
"%s::begin(channels=%d, sample_rate=%d)",
"SineWaveGenerator",
163 bool begin(
AudioInfo info,
float frequency) {
164 LOGI(
"%s::begin(channels=%d, sample_rate=%d, frequency=%.2f)",
168 if (frequency > 0.0f) {
174 bool begin(
int channels,
int sample_rate,
float frequency) {
192 LOGI(
"setFrequency: %.2f", frequency);
194 m_frequency = frequency;
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) {
208 void setAmplitude(
float amp) { m_amplitude = amp; }
211 volatile float m_frequency = 0.0f;
212 float m_cycles = 0.0f;
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;
219 SoundGenerator<T>::info.logStatus();
220 LOGI(
"amplitude: %f", this->m_amplitude);
221 LOGI(
"active: %s", SoundGenerator<T>::active ?
"true" :
"false");
237 LOGD(
"FastSineGenerator");
255 float p = (t - (int)t) - 0.5f;
257 return (p - 6.283211f * pp * p + 9.132843f * pp * pp * p) * -6.221086f;
272 LOGD(
"SquareWaveGenerator");
282 T value(T value, T amplitude) {
283 return (value >= 0) ? amplitude : -amplitude;
299 LOGD(
"SawToothGenerator");
316 inline float saw(
float t) {
317 float p = (t - (int)t) - 0.5f;
340 int random(
int min,
int max) {
return min + rand() % ((max + 1) - min); }
354 this->amplitude = amplitude;
357 for (
int i = 0; i < 5; i++)
358 white_values[i] = rand() % (amplitude / 5);
371 int diff = last_key ^ key;
373 for (
int i = 0; i < 5; i++) {
377 white_values[i] = rand() % (amplitude / 5);
378 sum += white_values[i];
386 unsigned int white_values[5];
387 unsigned int amplitude;
439 setChannels(channels);
445 void setChannels(
int channels) { this->channels = channels; }
451 if (p_stream !=
nullptr) {
452 for (
int j = 0; j < channels; j++) {
453 p_stream->readBytes((uint8_t *)&data,
sizeof(T));
456 float avg = (total / channels) *
volume();
457 if (avg > maxValue) {
459 }
else if (avg < -maxValue) {
469 Stream *p_stream =
nullptr;
498 template <
size_t arrayLen>
500 bool setInactiveAtEnd =
false,
size_t startIndex = 0) {
502 this->max_repeat = repeat;
503 this->inactive_at_end = setInactiveAtEnd;
504 this->sound_index = startIndex;
505 setArray(array, arrayLen);
514 template <
int arrayLen>
void setArray(T (&array)[arrayLen]) {
516 setArray(array, arrayLen);
519 void setArray(T *array,
size_t size) {
520 this->table_length = size;
522 LOGI(
"table_length: %d", (
int)size);
525 virtual bool begin(AudioInfo info)
override {
526 return SoundGenerator<T>::begin(info);
542 if (sound_index >= table_length) {
547 if (max_repeat >= 1 && ++repeat_counter >= max_repeat) {
549 this->is_running =
false;
550 if (inactive_at_end) {
551 this->active =
false;
558 if (this->is_running) {
559 result = table[sound_index];
560 sound_index += index_increment;
567 void setIncrement(
int inc) { index_increment = inc; }
570 int setupSine(
int sampleRate,
float reqFrequency,
float amplitude = 1.0) {
572 static_cast<float>(sampleRate) /
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;
580 table_length = sample_count;
582 return sampleRate / sample_count;
586 bool isRunning() {
return is_running; }
591 int repeat_counter = 0;
592 bool inactive_at_end;
593 bool is_running =
false;
594 bool owns_data =
false;
596 size_t table_length = 0;
597 int index_increment = 1;
613 void setValue(T value) { value_set = value; }
620 value_return = value_set;
628 bool isRunning() {
return is_running; }
633 bool is_running =
false;
646 this->amplitude = amplitude;
647 this->amplitude_to_be = amplitude;
651 void setAmplitude(
float amplitude) { this->amplitude_to_be = amplitude; }
660 if (angle >= 360.0f) {
661 while (angle >= 360.0f) {
667 updateAmplitudeInSteps();
670 return interpolate(angle);
681 bool begin(AudioInfo info,
float frequency) {
682 SoundGenerator<T>::begin(info);
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);
696 step_new = freq / base_frequency;
701 LOGD(
"step: %f", step_new);
705 bool is_first =
true;
707 float amplitude_to_be;
708 float max_amplitude_step = 50.0f;
709 float base_frequency = 1.0f;
711 float step_new = 1.0f;
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,
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);
757 return positive ? result : -result;
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;
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;
769 if (abs(diff) >= 1.0f) {
789 void clear() { vector.clear(); }
794 for (
auto &generator : vector) {
801 return count > 0.0f ? total / count : 0;
806 int actualChannel = 0;
823 if (abs(value) >= max) {